ERR_CRYPTO_INVALID_STATE
Node.jsERRORNotableCryptoHIGH confidence

Crypto operation called on object in invalid state

Production Risk

Can cause authentication to fail silently if the tag is not properly retrieved.

What this means

Thrown when a cryptographic object (such as a Cipher, Decipher, or ECDH object) is used in a state that does not support the requested operation. For example, calling cipher.getAuthTag() before cipher.final() has been called, or calling a method on an already-finalised object.

Why it happens
  1. 1Calling cipher.getAuthTag() before cipher.final() on an AEAD cipher
  2. 2Using a crypto object after it has been finalised
  3. 3Calling decipher.setAuthTag() after decryption has started
How to reproduce

Triggered when a crypto object method is called in an incompatible lifecycle state.

trigger — this will error
trigger — this will error
const { createCipheriv, randomBytes } = require('crypto');
const key = randomBytes(32);
const iv = randomBytes(12);
const cipher = createCipheriv('aes-256-gcm', key, iv);
cipher.update('data');
cipher.getAuthTag(); // throws — must call final() first

expected output

Error [ERR_CRYPTO_INVALID_STATE]: Invalid state for operation getAuthTag

Fix

Call final() before getAuthTag() for AEAD ciphers

WHEN When using AES-GCM or ChaCha20-Poly1305

Call final() before getAuthTag() for AEAD ciphers
const cipher = createCipheriv('aes-256-gcm', key, iv);
const encrypted = Buffer.concat([
  cipher.update('hello world'),
  cipher.final(),
]);
const tag = cipher.getAuthTag(); // safe after final()

Why this works

final() completes the encryption and computes the authentication tag; only then is getAuthTag() valid.

Code examples
Triggerjs
const { createCipheriv, randomBytes } = require('crypto');
const key = randomBytes(32);
const iv = randomBytes(12);
const cipher = createCipheriv('aes-256-gcm', key, iv);
cipher.update('data');
cipher.getAuthTag(); // throws — must call final() first  // this triggers ERR_CRYPTO_INVALID_STATE
Handle in try/catchjs
try {
  // operation that may throw ERR_CRYPTO_INVALID_STATE
  riskyOperation()
} catch (err) {
  if (err.code === 'ERR_CRYPTO_INVALID_STATE') {
    console.error('ERR_CRYPTO_INVALID_STATE:', err.message)
  } else {
    throw err
  }
}
Defensive pattern to avoid itjs
const cipher = createCipheriv('aes-256-gcm', key, iv)
const encrypted = Buffer.concat([cipher.update('data'), cipher.final()])
const tag = cipher.getAuthTag()  // call final() before getAuthTag()
What not to do

Call getAuthTag() before final()

The tag is not computed until the cipher is finalised; calling it early yields an invalid state error.

Same error in other languages
Sources
Official documentation ↗

Node.js Error Codes Documentation

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All Node.js errors