百科 / 错误代码 / Class 28 授权规范无效
28P01 invalid_password
密码无效
ERROR 已实测 详解 实测通过
- 条件名
invalid_password- 宏名称
ERRCODE_INVALID_PASSWORD- 启用版本
- 9.0
- 状态
- 活跃
版本覆盖
速览
28P01 是 PostgreSQL 类别 28 invalid_authorization_specification 中的 invalid_password 条件。客户端建立会话时密码认证失败,会产生这个代码。具体路径取决于认证方法、匹配的 pg_hba.conf 规则和角色保存的密码。
这是 SQL 执行前的失败。被拒绝的会话没有事务可供回滚。最终运行中,psycopg 返回了启动异常文本,但暴露的 sqlstate 为 None;PostgreSQL collector 记录了服务器实际发送的 FATAL SQLSTATE 28P01。不能把没有代码的驱动异常描述成客户端收到了 collector 字段。
案例 wrong_password_authentication 临时启用 md5 规则,使用错误密码连接,验证已知密码可以建立新会话并执行 SELECT 1,恢复原来的 HBA 配置,再验证新的管理连接。案例在 PostgreSQL 18.6 和隔离的 PostgreSQL 10.21 上均通过。run ID 和断言见公开证据 JSON。
含义与触发路径
服务器根据第一条匹配的 pg_hba.conf 规则选择认证方法。密码、MD5 和 SCRAM 路径拒绝提交的密码时,auth.c 选择 ERRCODE_INVALID_PASSWORD 并报告 FATAL。主报文模板是 password authentication failed for user "%s";服务器也可以在日志 detail 中加入匹配的 HBA 信息。
28P01 不会区分所有认证配置问题。角色不存在、角色不允许登录、证书失败,或 HBA 规则选择了其他方法,都可能使用不同的 SQLSTATE 或报文。匹配的规则和认证方法是诊断的一部分。
失败发生在连接启动阶段,后端尚未接受 SQL。连接池应丢弃被拒绝的连接尝试,在密码或 HBA 配置修好后建立新的连接。仍在使用的所有者或管理连接可以恢复临时规则,但复用它们不能证明受影响角色可以认证。
报文与诊断
下面的 SQL 语句与 runner 使用的密码设置和探针相同。运行时 known_user 和 example-known-secret 会替换为临时值。修改 pg_hba.conf 和使用错误密码建立连接属于启动操作,因此在 SQL 语句之间说明,而不是伪造 RAISE 或 SQL 错误。
ALTER ROLE known_user PASSWORD 'example-known-secret';
-- 在 pg_hba.conf 首行临时加入 host all all 0.0.0.0/0 md5。
-- 使用错误密码以 known_user 连接:启动阶段返回 FATAL 28P01。
-- 再使用已知密码建立连接并执行:
SELECT 1;
-- 恢复原 pg_hba.conf,建立新的管理连接并执行:
SELECT 1;
最新目标的 collector 记录形状为:
SQLSTATE: 28P01
severity: FATAL
message_primary: password authentication failed for user "<generated-role>"
detail (collector): Connection matched file "<pg_hba.conf path>" line 1: "host all all 0.0.0.0/0 md5"
source: auth.c / auth_failed / line 320
driver startup sqlstate: null
transaction: none opened
repair: known-password SELECT 1 -> 1; restore HBA; fresh owner SELECT 1 -> 1
PostgreSQL 10.21 的 collector 产生相同的主报文和 SQLSTATE,源码位置为 auth.c:329;其 collector detail 使用较早的 pg_hba.conf line 表述,并且还包含密码不匹配行。两个目标都在临时规则下用已知密码认证成功,重新加载原 HBA 配置,并让新的管理连接返回 1。驱动文本和 collector 字段是两条独立证据;本次运行中 libpq/psycopg 没有暴露启动 SQLSTATE。
报文模板
源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。
password authentication failed for user "%s"
Connection matched file "%s" line %d: "%s"
来源:src/backend/libpq/auth.c(lines 270-332) @ REL_18_6
适用范围:The fixed PG18.6 source passes logdetail through errdetail_log; a client ErrorResponse need not expose it. PG10 collector output uses a release-specific pg_hba.conf wording and may include an additional password-mismatch line.
诊断
记录用户、数据库、连接来源、认证方法、服务器版本和第一条匹配的 HBA 规则,不要记录密码。按时间关联失败尝试和 verbose collector 记录。collector detail 可以指出 HBA 行,而客户端启动异常可能只有 FATAL 文本。
检查目标角色存在且允许登录,密码已针对选定方法设置,并确认更早的 HBA 规则没有截获连接。正确密码配在错误的 HBA 方法上不能证明部署正确。密码轮换完成前,应等待新的连接成功。
被拒绝的会话没有事务状态需要恢复。修改 HBA 规则时保留受控的管理连接,重新加载配置,并用新的客户端测试。测试完成后精确恢复原规则,再确认新的所有者连接仍可用。
处理与修复
- 为角色使用预期的密码和认证方法,通过不会把密码暴露到日志或命令历史的途径轮换密码。
- 检查第一条匹配的
pg_hba.conf规则,修正数据库、用户、地址和方法字段,然后重新加载配置。 - 用新的连接和真实的无害查询(例如
SELECT 1)测试受影响角色。 - 在新路径得到证明前保留管理访问,随后关闭仍保存旧密码的连接池陈旧会话。
代表性修复同时包含已知密码连接和恢复后的新管理连接。仅成功调用 pg_reload_conf() 不能证明认证已经修好,复用执行 reload 的连接也不能测试修复后的登录路径。
可复现案例
在一次性实例上执行过的场景。其中 1 个附有可执行 SQL,正文相应小节里给出。
wrong_password_authentication PG 10 / 18 有 SQL
前置条件
- A disposable login role with a known password
- A temporary first pg_hba.conf rule uses md5 and is reloaded
触发
Connect with a wrong password and retain the server's authentication diagnostic.
断言
- The connection attempt receives SQLSTATE 28P01
- The server does not open a transaction for the rejected connection
- The known password opens a new session while the temporary rule is active
- A fresh management connection succeeds after the original configuration is restored
处置
Use the intended secret and authentication method, verify a new connection, then restore or rotate credentials without logging passwords.
清理
Restore pg_hba.conf and drop the role and schema.
版本与边界
目录在第一份扫描到的定义(9.0.0 或更早)中已包含 28P01,并在列出的所有正式快照直到 PostgreSQL 18.6 以及 PostgreSQL 19 Beta 3 预览中存在。扫描范围内没有记录该条件的定义变化;9.0 以前的引入点仍未扫描。
错误密码案例在 PostgreSQL 18.6 和 10.21 上通过。源码行号随版本变化,驱动与 collector 的 SQLSTATE 差异是本启动路径的实测边界。证书、GSSAPI、PAM、LDAP、peer 和 HBA 语法失败是独立认证路径,本证据不覆盖。
来源
- 核验材料 verify/cases/28P01/cases.json
- 核验材料 doc/src/sgml/client-auth.sgml
- 核验材料 doc/src/sgml/protocol.sgml
- 核验材料 sources/manifest.lock.json
- 核验材料 verify/cases/28P01/snippets.json
- 核验材料 src/backend/libpq/auth.c 第 270–332 行
- 核验材料 src/backend/utils/errcodes.txt
证据
断言
每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。
-
28P01 is the invalid_password condition in Class 28 invalid_authorization_specification.
-
The password authentication failure path in auth.c selects ERRCODE_INVALID_PASSWORD, reports password authentication failed for user "%s" at FATAL, and may add the matched pg_hba.conf line to log detail.
-
For the rejected startup connection, psycopg exposed startup text with sqlstate null while the PostgreSQL collector recorded FATAL SQLSTATE 28P01 and the password-failure message on both targets.
-
After enabling the temporary md5 rule, the known password opened a new role connection and returned SELECT 1 = 1; after exact HBA restoration, a fresh management connection also returned 1 on both targets.
-
The locked catalogue records 28P01 in every listed formal snapshot from 9.0.23 through 18.6 and in 19beta3; pre-9.0 history is not scanned.
运行记录
| 目标 | 服务器版本 | 结果 | 覆盖案例 |
|---|---|---|---|
| latest | 18.6 (Homebrew) | passed | wrong_password_authentication |
| pg10 | 10.21 (Debian 10.21-1.pgdg90+1) | passed | wrong_password_authentication |
同类错误代码
Class 28 授权规范无效 下的其他成员。