选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / 错误代码 / Class 28 授权规范无效

28P01 invalid_password

密码无效

ERROR 已实测 详解 实测通过

类别
Class 28 授权规范无效
严重等级
ERROR
条件名
invalid_password
宏名称
ERRCODE_INVALID_PASSWORD
启用版本
9.0
状态
活跃

版本覆盖

速览

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

含义与触发路径

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

报文模板

源码里的格式串,不是某一次运行的输出。%s 之类是占位符,实际报文会填入对象名与取值。适用范围一栏是核验时留下的原始英文记录,未经翻译。

主消息 password authentication failed for user "%s"
DETAIL 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 语法失败是独立认证路径,本证据不覆盖。

来源

证据

断言

每条断言都写明了是怎么核实的,以及它不覆盖什么。这一层是核验时留下的原始英文记录,照原样呈现,未经翻译。

  • 28P01 is the invalid_password condition in Class 28 invalid_authorization_specification.

    核实方式Read the Class 28 section and 28P01 row in the frozen errcodes.txt snapshot.

    不覆盖Directory identity does not identify the selected authentication method or the matched HBA rule.

    来源src/backend/utils/errcodes.txt(lines 271-278)

  • 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.

    核实方式Trace auth_failed's password/MD5/SCRAM error selection and detail construction and compare the official HBA and password-authentication rules.

    不覆盖Other authentication methods and HBA configuration errors use separate branches and can report different SQLSTATEs or messages.

    来源src/backend/libpq/auth.c(lines 270-332) · doc/src/sgml/client-auth.sgml(pg_hba.conf and password authentication)

  • 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.

    核实方式Compare driver diagnostics and collector SQL state code, severity, message, HBA detail, and source location in both final summaries and raw records.

    不覆盖Driver exposure can vary by client and startup failure; the collector record is the server-side SQLSTATE evidence here.

    来源doc/src/sgml/protocol.sgml(ErrorResponse fields)

  • 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.

    核实方式Use an owner connection to set the disposable role password, reload the temporary HBA rule, test wrong and known passwords through new connections, restore and reload the original rule, and assert a fresh owner probe.

    不覆盖The run proves a password failure under the controlled md5 rule; it does not cover certificate, GSSAPI, PAM, LDAP, peer, or HBA syntax failures.

    来源verify/cases/28P01/cases.json(wrong_password_authentication) · verify/cases/28P01/snippets.json(wrong_password_authentication ordered SQL)

  • 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.

    核实方式Read the manifest snapshots and definition references for the code.

    不覆盖The first scanned release is a lower bound, not an asserted introduction version.

    来源sources/manifest.lock.json(snapshots and definition_blobs entries for the 28P01 definition)

运行记录

目标服务器版本结果覆盖案例
latest 18.6 (Homebrew) passed wrong_password_authentication
pg10 10.21 (Debian 10.21-1.pgdg90+1) passed wrong_password_authentication

同类错误代码

Class 28 授权规范无效 下的其他成员。