{"record":{"id":"dc43ccc7a7be94fd","repo":"denoland/deno","slug":"trying-to-add-data-in-unsupported-state","errorCode":null,"errorMessage":"Trying to add data in unsupported state","messagePattern":"Trying to add data in unsupported state","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/crypto/cipher.ts","lineNumber":360,"sourceCode":"  outputEncoding: any = getDefaultEncoding(),\n): Buffer | string {\n  if (this._finalized) {\n    throw new ERR_CRYPTO_INVALID_STATE(\"update\");\n  }\n\n  validateCipherUpdateData(data);\n\n  let buf = data;\n  if (typeof data === \"string\") {\n    buf = Buffer.from(data, inputEncoding);\n  } else {\n    buf = toFastBufferView(data);\n  }\n  const inputByteLength = getArrayBufferViewByteLength(buf);\n\n  // Match Node.js/OpenSSL behavior: reject inputs >= INT_MAX bytes\n  if (inputByteLength >= 2 ** 31 - 1) {\n    throw new Error(\"Trying to add data in unsupported state\");\n  }\n\n  _lazyInitCipherDecoder(this, outputEncoding);\n\n  if (this._isAesWrap) {\n    const output = Buffer.from(\n      op_node_aes_wrap_key(\n        this._aesWrapAlgorithm,\n        this._aesWrapKey,\n        this._aesWrapIv,\n        buf,\n      ),\n    );\n    if (outputEncoding !== \"buffer\") {\n      return this._decoder!.write(output);\n    }\n    return output;\n  }","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/crypto/cipher.ts#L342-L378","documentation":"update() rejects inputs whose byte length is >= 2^31 - 1 (2147483647, about 2 GiB), matching the INT_MAX single-call limit of Node/OpenSSL's CipherBase. This is a plain Error (no code property) reusing Node's literal message 'Trying to add data in unsupported state'.","triggerScenarios":"cipher.update(hugeBuffer) where the buffer was built by concatenating an entire file; passing a giant preallocated TypedArray; Batch jobs that accumulate logs/media into one buffer before a single encrypt call.","commonSituations":"Whole-file encryption of large media, dumps, or backups; log-shipping pipelines that batch everything into memory; switching from per-chunk encryption to one-shot encryption without chunking.","solutions":["Encrypt as a stream: feed update() with fixed-size chunks (e.g. 64 KiB to 1 MiB) as data is read.","Do not load the whole payload into memory; pipe a read stream through the cipher.","If pre-validation is needed, check the input's byte length < 2 ** 31 - 1 before calling update()."],"exampleFix":"// before\nconst whole = readEntireFile('backup.tar'); // > 2 GiB\ncipher.update(whole); // Error: Trying to add data in unsupported state\n\n// after\nconst CHUNK = 1 << 20; // 1 MiB\nfor await (const chunk of readFileIter('backup.tar')) {\n  const piece = chunk.length > CHUNK ? chunk : chunk; // stream naturally chunked\n  out.write(cipher.update(piece.subarray(0, CHUNK)));\n  if (chunk.length > CHUNK) out.write(cipher.update(chunk.subarray(CHUNK)));\n}\nout.write(cipher.final());","handlingStrategy":"validation","validationCode":"const MAX_UPDATE_BYTES = 2 ** 31 - 2; // stay under the 2^31-1 limit\nfunction assertUpdatableSize(input: Buffer | ArrayBufferView | string): void {\n  const len = typeof input === 'string' ? Buffer.byteLength(input) : input.byteLength;\n  if (len >= 2 ** 31 - 1)\n    throw new RangeError(`input of ${len} bytes exceeds single-update limit; chunk it`);\n}\nfunction* chunks(buf: Buffer, size = 1 << 20): Generator<Buffer> {\n  for (let i = 0; i < buf.length; i += size) yield buf.subarray(i, i + size);\n}","typeGuard":null,"tryCatchPattern":"try { out = cipher.update(buf); } catch (e) { if (e.message === 'Trying to add data in unsupported state' && buf.length >= 2 ** 31 - 1) { out = Buffer.concat([...chunks(buf)].map((c) => cipher.update(c))); } else throw e; }","preventionTips":["Design encryption as a streaming pipeline from day one; never buffer whole files.","Chunk large inputs explicitly (64 KiB-1 MiB per update is a safe habit).","Check byteLength of untrusted-sized inputs before one-shot update calls."],"tags":["crypto","cipher","size-limit","streaming","node-compat"],"backgroundTag":"input-size-limit-exceeded","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}