{"id":"83aa1bae2c015e13","repo":"jackc/pgx","slug":"bad-authentication-message-size-83aa1b","errorCode":null,"errorMessage":"bad authentication message size","messagePattern":"bad authentication message size","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgproto3/authentication_md5_password.go","lineNumber":26,"sourceCode":"\t\"github.com/jackc/pgx/v5/internal/pgio\"\n)\n\n// AuthenticationMD5Password is a message sent from the backend indicating that an MD5 hashed password is required.\ntype AuthenticationMD5Password struct {\n\tSalt [4]byte\n}\n\n// Backend identifies this message as sendable by the PostgreSQL backend.\nfunc (*AuthenticationMD5Password) Backend() {}\n\n// Backend identifies this message as an authentication response.\nfunc (*AuthenticationMD5Password) AuthenticationResponse() {}\n\n// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message\n// type identifier and 4 byte message length.\nfunc (dst *AuthenticationMD5Password) Decode(src []byte) error {\n\tif len(src) != 8 {\n\t\treturn errors.New(\"bad authentication message size\")\n\t}\n\n\tauthType := binary.BigEndian.Uint32(src)\n\n\tif authType != AuthTypeMD5Password {\n\t\treturn errors.New(\"bad auth type\")\n\t}\n\n\tcopy(dst.Salt[:], src[4:8])\n\n\treturn nil\n}\n\n// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length.\nfunc (src *AuthenticationMD5Password) Encode(dst []byte) ([]byte, error) {\n\tdst, sp := beginMessage(dst, 'R')\n\tdst = pgio.AppendUint32(dst, AuthTypeMD5Password)\n\tdst = append(dst, src.Salt[:]...)","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgproto3/authentication_md5_password.go#L8-L44","documentation":"Returned by AuthenticationMD5Password.Decode in pgproto3/authentication_md5_password.go:26 when the body is not exactly 8 bytes. The MD5 auth message is fixed-size: 4 bytes for the auth code (AuthTypeMD5Password = 5) plus 4 bytes for the salt. Any other length is a protocol violation; the salt (src[4:8]) could not be safely copied.","triggerScenarios":"Server/intermediary sends an MD5 auth frame with a body length other than 8; truncated stream; non-PostgreSQL responder; direct Decode on malformed bytes.","commonSituations":"Connecting to the wrong port/service whose greeting mimics 'R'; proxy mangling the startup frame; flaky link truncating the 8-byte body; fuzz input in a proxy.","solutions":["Confirm a real PostgreSQL server is at the address (psql works).","Bypass pooler/proxy to rule out frame corruption.","In direct pgproto3 use, require len(body) == 8 before MD5 Decode."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"conn, err := pgconn.Connect(ctx, connString)\nif err != nil {\n    if strings.Contains(err.Error(), \"bad authentication message size\") {\n        return fmt.Errorf(\"malformed MD5 auth frame from %s: %w\", connString, err)\n    }\n    return err\n}","preventionTips":["Verify the host:port is a genuine PostgreSQL server (psql connects).","Bypass pooler/proxy to rule out frame corruption of the 8-byte MD5 body.","In direct pgproto3 use, assert len(body)==8 before AuthenticationMD5Password.Decode."],"tags":["authentication","protocol","md5","pgproto3","connection"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}