brianc/node-postgres · error · Error

SASL: Invalid attribute pair entry

Error message

SASL: Invalid attribute pair entry

What it means

Thrown by parseAttributePairs (sasl.js:181-184) when a comma-separated segment of a SCRAM message does not match the expected '<letter>=' format. SCRAM attribute pairs are single-letter keys (r, s, i, v, etc.) followed by '=' and a value; a segment that lacks the '=' delimiter or has a multi-character/malformed key indicates a corrupt or non-compliant server message. The regex /^.=/ requires exactly one char then '=' at the start of each segment.

Source

Thrown at packages/pg/lib/crypto/sasl.js:183

 * base64-3        = 3base64-char "="
 *
 * base64-2        = 2base64-char "=="
 *
 * base64          = *base64-4 [base64-3 / base64-2]
 */
function isBase64(text) {
  return /^(?:[a-zA-Z0-9+/]{4})*(?:[a-zA-Z0-9+/]{2}==|[a-zA-Z0-9+/]{3}=)?$/.test(text)
}

function parseAttributePairs(text) {
  if (typeof text !== 'string') {
    throw new TypeError('SASL: attribute pairs text must be a string')
  }

  return new Map(
    text.split(',').map((attrValue) => {
      if (!/^.=/.test(attrValue)) {
        throw new Error('SASL: Invalid attribute pair entry')
      }
      const name = attrValue[0]
      const value = attrValue.substring(2)
      return [name, value]
    })
  )
}

function parseServerFirstMessage(data) {
  const attrPairs = parseAttributePairs(data)

  const nonce = attrPairs.get('r')
  if (!nonce) {
    throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: nonce missing')
  } else if (!isPrintableChars(nonce)) {
    throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: nonce must only contain printable characters')
  }
  const salt = attrPairs.get('s')

View on GitHub (pinned to c5e8c9a57b)

Solutions

  1. Verify you are connecting to a genuine PostgreSQL server with a compliant SCRAM implementation.
  2. If behind a proxy/pooler, ensure it forwards SCRAM messages unmodified.
  3. Enable SSL to prevent wire-level corruption or tampering.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.connect();
} catch (err) {
  if (/Invalid attribute pair entry/i.test(err.message)) {
    console.error('Malformed SCRAM message from server — check for non-compliant proxy or corruption.');
  }
  throw err;
}

Prevention

When it happens

Trigger: A SCRAM server message containing a segment like 'rx' (no '=') or 'nonce=abc' (multi-char key). This is parsed from the serverData string in either parseServerFirstMessage or parseServerFinalMessage.

Common situations: A non-compliant PostgreSQL-compatible server or proxy injecting malformed SCRAM attributes. Data corruption on the wire. Extremely rare with genuine PostgreSQL backends, as their SCRAM messages are well-formed.

Related errors


AI-assisted analysis of brianc/node-postgres@c5e8c9a57b (2026-08-03). Data as JSON: /data/errors/78ce6505edf9fd53.json. Report an issue: GitHub.