brianc/node-postgres · error · Error

SASL: SCRAM-SERVER-FIRST-MESSAGE: nonce missing

Error message

SASL: SCRAM-SERVER-FIRST-MESSAGE: nonce missing

What it means

Thrown by parseServerFirstMessage (sasl.js:195-197) when the server's first SCRAM message has no 'r' attribute (the combined nonce). The nonce is mandatory in the server-first message per RFC 5802; its absence indicates a truncated or malformed message. The code reads attrPairs.get('r') and throws if it is falsy.

Source

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

  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')
  if (!salt) {
    throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: salt missing')
  } else if (!isBase64(salt)) {
    throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: salt must be base64')
  }
  const iterationText = attrPairs.get('i')
  if (!iterationText) {
    throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: iteration missing')
  } else if (!/^[1-9][0-9]*$/.test(iterationText)) {
    throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: invalid iteration count')
  }
  const iteration = parseInt(iterationText, 10)

  return {

View on GitHub (pinned to c5e8c9a57b)

Solutions

  1. Verify the target is a genuine, unproxied PostgreSQL server.
  2. Check for PgBouncer or other intermediaries that may alter SASL messages.
  3. Enable SSL to ensure message integrity during authentication.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await client.connect();
} catch (err) {
  if (/nonce missing/i.test(err.message)) {
    console.error('SCRAM first message missing nonce — non-compliant server or truncated message.');
  }
  throw err;
}

Prevention

When it happens

Trigger: The server's AuthenticationSASLContinue payload lacks the r=<nonce> attribute. This is parsed from the serverData string passed to continueSession.

Common situations: A non-compliant server sending an incomplete SCRAM first message. A proxy truncating the message. Wire-level corruption. Rare with genuine PostgreSQL.

Related errors


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