跳转到主要内容

28P01 — invalid_password(密码无效)

密码认证在连接启动阶段失败时,PostgreSQL 会报告 SQLSTATE 28P01。应检查匹配的 pg_hba.conf 规则和角色密码,并用新的连接证明修复。

速览

28P01 是 PostgreSQL 类别 28 invalid_authorization_specification 中的 invalid_password 条件。客户端建立会话时密码认证失败,会产生这个代码。具体路径取决于认证方法、匹配的 pg_hba.conf 规则和角色保存的密码。

这是 SQL 执行前的失败。被拒绝的会话没有事务可供回滚。最终运行中,psycopg 返回了启动异常文本,但暴露的 sqlstateNone;PostgreSQL collector 记录了服务器实际发送的 FATAL SQLSTATE 28P01。不能把没有代码的驱动异常描述成客户端收到了 collector 字段。

案例 wrong_password_authentication 临时启用 md5 规则,使用错误密码连接,验证已知密码可以建立新会话并执行 SELECT 1,恢复原来的 HBA 配置,再验证新的管理连接。案例在 PostgreSQL 18.6 和隔离的 PostgreSQL 10.21 上均通过。run ID 和断言见公开证据 JSON

字段
SQLSTATE 28P01
条件名 invalid_password
状态 有效
已知存在于 9.0.0
锁定快照 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3
ERRCODE_INVALID_PASSWORD
别名

含义与触发路径

服务器根据第一条匹配的 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_userexample-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。

诊断

记录用户、数据库、连接来源、认证方法、服务器版本和第一条匹配的 HBA 规则,不要记录密码。按时间关联失败尝试和 verbose collector 记录。collector detail 可以指出 HBA 行,而客户端启动异常可能只有 FATAL 文本。

检查目标角色存在且允许登录,密码已针对选定方法设置,并确认更早的 HBA 规则没有截获连接。正确密码配在错误的 HBA 方法上不能证明部署正确。密码轮换完成前,应等待新的连接成功。

被拒绝的会话没有事务状态需要恢复。修改 HBA 规则时保留受控的管理连接,重新加载配置,并用新的客户端测试。测试完成后精确恢复原规则,再确认新的所有者连接仍可用。

处理与修复

  • 为角色使用预期的密码和认证方法,通过不会把密码暴露到日志或命令历史的途径轮换密码。
  • 检查第一条匹配的 pg_hba.conf 规则,修正数据库、用户、地址和方法字段,然后重新加载配置。
  • 用新的连接和真实的无害查询(例如 SELECT 1)测试受影响角色。
  • 在新路径得到证明前保留管理访问,随后关闭仍保存旧密码的连接池陈旧会话。

代表性修复同时包含已知密码连接和恢复后的新管理连接。仅成功调用 pg_reload_conf() 不能证明认证已经修好,复用执行 reload 的连接也不能测试修复后的登录路径。

版本与边界

目录在第一份扫描到的定义(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 语法失败是独立认证路径,本证据不覆盖。

53300too_many_connections 是连接启动阶段的容量失败。57014query_canceled 发生在已连接后端执行语句时。42501insufficient_privilege 是认证后的权限检查,不是密码诊断。

来源

结构化证据记录在公开证据 JSON中。源码记录固定到 PostgreSQL commit 724edf9bde9d356724ad384a2e196edc3c9f80f7;运行记录保留 collector 输出、驱动观察、HBA 恢复、两个目标 ID 和结构化观察。