denoland/deno · error · TypeError
ERR_UNKNOWN_ENCODING
ERR_UNKNOWN_ENCODING
Error message
Unknown encoding: ${encoding} What it means
_lazyInitCipherDecoder builds a StringDecoder for the output encoding requested by update(data, inputEnc, outputEnc) or final(encoding). normalizeEncoding() must map the string to a known encoding or ERR_UNKNOWN_ENCODING is thrown; only encodings StringDecoder supports are valid (utf8/utf-8, utf16le, latin1/binary, ascii, base64, base64url, hex). Passing 'buffer' skips decoder creation entirely.
Source
Thrown at ext/node/polyfills/internal/crypto/cipher.ts:423
if (outputEncoding !== "buffer") {
return this._decoder!.write(output);
}
return output;
};
function _lazyInitCipherDecoder(self: any, encoding: string) {
if (encoding === "buffer") {
return;
}
const normalizedEncoding = normalizeEncoding(encoding);
self._decoder ||= new StringDecoder(normalizedEncoding);
if (self._decoder.encoding !== normalizedEncoding) {
if (normalizedEncoding === undefined) {
throw new ERR_UNKNOWN_ENCODING(encoding);
}
assert(false, "Cannot change encoding");
}
}
/** Caches data and output the chunk of multiple of 16.
* Used by CBC, ECB modes of block ciphers */
class BlockModeCache {
cache: Uint8Array;
blockSize: number;
// The last chunk can be padded when decrypting.
#lastChunkIsNonZero: boolean;
constructor(lastChunkIsNotZero = false, blockSize = 16) {
this.cache = new Uint8Array(0);
this.blockSize = blockSize;
this.#lastChunkIsNonZero = lastChunkIsNotZero;
}View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Use exact supported names: 'utf8', 'utf16le', 'latin1', 'ascii', 'base64', 'base64url', 'hex'.
- Omit the encoding or pass 'buffer' when you want Buffer output rather than a string.
- Validate encodings against an allow-list before calling update()/final().
Example fix
// before const s = cipher.update(data, 'utf8', 'utf-16'); // ERR_UNKNOWN_ENCODING // after const s = cipher.update(data, 'utf8', 'utf16le'); // or 'utf8' / 'base64' / 'buffer'
Defensive patterns
Strategy: validation
Validate before calling
const STRING_DECODER_ENCODINGS = new Set([
'utf8','utf-8','utf16le','utf-16le','latin1','binary','ascii','base64','base64url','hex',
]);
function assertEncoding(enc: string): void {
if (enc !== 'buffer' && !STRING_DECODER_ENCODINGS.has(enc.toLowerCase()))
throw new TypeError(`Unknown encoding: ${enc}`);
} Try / catch
try { s = cipher.final(enc); } catch (e) { if (e.code === 'ERR_UNKNOWN_ENCODING') { s = cipher.final('buffer').toString(enc === 'base64-url' ? 'base64url' : 'utf8'); } else throw e; } Prevention
- Prefer 'buffer' output and call .toString(encoding) yourself with a validated name.
- Use 'base64url' (not 'base64-url') and 'utf16le' (not 'utf-16').
- Validate config-supplied encoding names against a constant set at startup.
When it happens
Trigger: cipher.update(data, 'utf8', 'base62') (made-up name); cipher.final('base64-url') instead of 'base64url'; an undefined encoding variable after refactor; swapping the inputEncoding and outputEncoding arguments.
Common situations: Encoding names read from config or user input; typos like 'hex ' with trailing space or 'utf-16' instead of 'utf16le'; code ported from iconv-style libraries with different encoding aliases.
Related errors
- ERR_INVALID_ARG_TYPE
- ERR_CRYPTO_UNKNOWN_CIPHER
- ERR_CRYPTO_INVALID_STATE
- Trying to add data in unsupported state
- ERR_INVALID_ARG_VALUE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/c28292cee95667d6.
Report an issue: GitHub.