brianc/node-postgres · error · Error

Buffers cannot be empty

Error message

Buffers cannot be empty

What it means

Thrown by xorBuffers() when both input Buffers have length 0. This function XORs two equal-length Buffers to compute the client proof during SCRAM authentication. Since it operates on HMAC-SHA256 outputs (always 32 bytes), empty buffers are impossible under correct crypto operation — this guard fires only if the crypto layer returned empty data.

Source

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

    throw new Error('SASL: SCRAM-SERVER-FINAL-MESSAGE: server signature must be base64')
  }
  return {
    serverSignature,
  }
}

function xorBuffers(a, b) {
  if (!Buffer.isBuffer(a)) {
    throw new TypeError('first argument must be a Buffer')
  }
  if (!Buffer.isBuffer(b)) {
    throw new TypeError('second argument must be a Buffer')
  }
  if (a.length !== b.length) {
    throw new Error('Buffer lengths must match')
  }
  if (a.length === 0) {
    throw new Error('Buffers cannot be empty')
  }
  return Buffer.from(a.map((_, i) => a[i] ^ b[i]))
}

module.exports = {
  startSession,
  continueSession,
  finalizeSession,
  DEFAULT_MAX_SCRAM_ITERATIONS,
}

View on GitHub (pinned to ff9d775abd)

Solutions

  1. If using a custom crypto shim or polyfill in packages/pg/lib/crypto/utils.js, ensure hmacSha256 returns a correct 32-byte output.
  2. Verify Node.js crypto is functioning correctly — run a simple HMAC test outside of pg.
  3. Reinstall node-postgres cleanly to restore the default crypto implementation.
  4. In test environments, ensure any crypto mocks return realistic 32-byte outputs.
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify crypto module is functional (relevant for test/custom environments):
const crypto = require('crypto')
const result = crypto.createHmac('sha256', 'key').update('Client Key').digest()
if (result.length !== 32) {
  throw new Error('HMAC-SHA256 is broken in this environment')
}

Try / catch

try {
  await client.connect()
} catch (err) {
  if (err.message.includes('Buffers cannot be empty')) {
    // Crypto module is returning empty output — environment or crypto shim issue
    throw new Error('Internal crypto failure — verify Node.js crypto module is intact')
  }
  throw err
}

Prevention

When it happens

Trigger: xorBuffers() is called at sasl.js:120 with Buffer.from(clientKey) and Buffer.from(clientSignature), both of which are outputs of crypto.hmacSha256(). HMAC-SHA256 always produces 32 bytes. If either Buffer is empty (length 0), the check at line 251-252 fires. This would require the crypto module's hmacSha256 to return an empty ArrayBuffer/Uint8Array.

Common situations: A broken or non-standard crypto implementation — e.g., a mock or stub in tests, a polyfill that doesn't correctly implement HMAC-SHA256, or a corrupted Node.js installation. Not reachable with Node.js's built-in crypto module under normal conditions.

Related errors


AI-assisted analysis of brianc/node-postgres@ff9d775abd (2026-08-11). Data as JSON: /api/errors/b0ccf4ec52eddf42. Report an issue: GitHub.