jackc/pgx · error
invalid SCRAM server-first-message received from server: did
Error message
invalid SCRAM server-first-message received from server: did not include i=
What it means
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=.
Source
Thrown at pgconn/auth_scram.go:266
return errors.New("invalid SCRAM server-first-message received from server: did not include r=")
}
buf = buf[2:]
idx := bytes.IndexByte(buf, ',')
if idx == -1 {
return errors.New("invalid SCRAM server-first-message received from server: did not include s=")
}
sc.clientAndServerNonce = buf[:idx]
buf = buf[idx+1:]
if !bytes.HasPrefix(buf, []byte("s=")) {
return errors.New("invalid SCRAM server-first-message received from server: did not include s=")
}
buf = buf[2:]
idx = bytes.IndexByte(buf, ',')
if idx == -1 {
return errors.New("invalid SCRAM server-first-message received from server: did not include i=")
}
saltStr := buf[:idx]
buf = buf[idx+1:]
if !bytes.HasPrefix(buf, []byte("i=")) {
return errors.New("invalid SCRAM server-first-message received from server: did not include i=")
}
buf = buf[2:]
iterationsStr := buf
var err error
sc.salt, err = base64.StdEncoding.DecodeString(string(saltStr))
if err != nil {
return fmt.Errorf("invalid SCRAM salt received from server: %w", err)
}
sc.iterations, err = strconv.Atoi(string(iterationsStr))
if err != nil || sc.iterations <= 0 {View on GitHub (pinned to ec1a0befd2)
Solutions
- Confirm a genuine, conformant PostgreSQL backend.
- Remove protocol-rewriting intermediaries.
- Capture and inspect the raw payload, then report the malformed message source.
Defensive patterns
Strategy: try-catch
Try / catch
if err := connect(); err != nil && strings.Contains(err.Error(), "did not include i=") {
return fmt.Errorf("malformed SCRAM iteration count from server: %w", err)
} Prevention
- Verify the server is conformant PostgreSQL.
- Eliminate protocol-mangling proxies.
- Capture the raw SASL payload if it recurs.
When it happens
Trigger: Server sends 'r=...,s=base64salt' with no trailing comma/iteration count. Same malformed-message class as the other server-first parse errors.
Common situations: Truncated/malformed SASL payloads from a buggy server or proxy; MITM corruption.
Related errors
- invalid SCRAM server-first-message received from server: did
- invalid SCRAM server-first-message received from server: did
- invalid SCRAM nonce: did not start with client nonce
- invalid SCRAM nonce: did not include server nonce
- invalid SCRAM server-final-message received from server
AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04).
Data as JSON: /data/errors/15a7c78e996ff6e9.json.
Report an issue: GitHub.