{"id":"15a7c78e996ff6e9","repo":"jackc/pgx","slug":"invalid-scram-server-first-message-received-from-s-15a7c7","errorCode":null,"errorMessage":"invalid SCRAM server-first-message received from server: did not include i=","messagePattern":"invalid SCRAM server-first-message received from server: did not include i=","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pgconn/auth_scram.go","lineNumber":266,"sourceCode":"\t\treturn errors.New(\"invalid SCRAM server-first-message received from server: did not include r=\")\n\t}\n\tbuf = buf[2:]\n\n\tidx := bytes.IndexByte(buf, ',')\n\tif idx == -1 {\n\t\treturn errors.New(\"invalid SCRAM server-first-message received from server: did not include s=\")\n\t}\n\tsc.clientAndServerNonce = buf[:idx]\n\tbuf = buf[idx+1:]\n\n\tif !bytes.HasPrefix(buf, []byte(\"s=\")) {\n\t\treturn errors.New(\"invalid SCRAM server-first-message received from server: did not include s=\")\n\t}\n\tbuf = buf[2:]\n\n\tidx = bytes.IndexByte(buf, ',')\n\tif idx == -1 {\n\t\treturn errors.New(\"invalid SCRAM server-first-message received from server: did not include i=\")\n\t}\n\tsaltStr := buf[:idx]\n\tbuf = buf[idx+1:]\n\n\tif !bytes.HasPrefix(buf, []byte(\"i=\")) {\n\t\treturn errors.New(\"invalid SCRAM server-first-message received from server: did not include i=\")\n\t}\n\tbuf = buf[2:]\n\titerationsStr := buf\n\n\tvar err error\n\tsc.salt, err = base64.StdEncoding.DecodeString(string(saltStr))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid SCRAM salt received from server: %w\", err)\n\t}\n\n\tsc.iterations, err = strconv.Atoi(string(iterationsStr))\n\tif err != nil || sc.iterations <= 0 {","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/pgconn/auth_scram.go#L248-L284","documentation":"Returned by recvServerFirstMessage when the salt attribute is present but no comma separator follows it, so the iteration-count attribute 'i=' cannot be located. RFC 5802 requires i= after s=.","triggerScenarios":"Server sends 'r=...,s=base64salt' with no trailing comma/iteration count. Same malformed-message class as the other server-first parse errors.","commonSituations":"Truncated/malformed SASL payloads from a buggy server or proxy; MITM corruption.","solutions":["Confirm a genuine, conformant PostgreSQL backend.","Remove protocol-rewriting intermediaries.","Capture and inspect the raw payload, then report the malformed message source."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := connect(); err != nil && strings.Contains(err.Error(), \"did not include i=\") {\n    return fmt.Errorf(\"malformed SCRAM iteration count from server: %w\", err)\n}","preventionTips":["Verify the server is conformant PostgreSQL.","Eliminate protocol-mangling proxies.","Capture the raw SASL payload if it recurs."],"tags":["authentication","scram","protocol","security"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}