denoland/deno · error · ERR_UNKNOWN_ENCODING

ERR_UNKNOWN_ENCODING

ERR_UNKNOWN_ENCODING

Error message

Unknown encoding: ${enc}

What it means

StringDecoder supports a fixed set of encodings — utf8, utf16le/ucs2, latin1/binary, base64, base64url, hex, ascii. normalizeEncoding calls castEncoding on the (possibly null) name and throws ERR_UNKNOWN_ENCODING when it cannot be mapped; notably the legacy 'raw' encoding is explicitly rejected rather than aliased.

Source

Thrown at ext/node/polyfills/string_decoder.ts:73

  Uint8Array,
} = primordials;
const { isTypedArray } = core;

const ENCODING_UTF8 = 0;
const ENCODING_BASE64 = 1;
const ENCODING_BASE64URL = 2;
const ENCODING_UTF16 = 3;
const ENCODING_ASCII = 4;
const ENCODING_LATIN1 = 5;
const ENCODING_HEX = 6;

function normalizeEncoding(enc) {
  const encoding = castEncoding(enc ?? null);
  if (!encoding) {
    if (
      typeof enc !== "string" || StringPrototypeToLowerCase(enc) !== "raw"
    ) {
      throw new ERR_UNKNOWN_ENCODING(
        enc,
      );
    }
  }
  return String(encoding);
}

function isBufferType(buf) {
  return ObjectPrototypeIsPrototypeOf(Buffer.prototype, buf) &&
    buf.BYTES_PER_ELEMENT;
}

function normalizeBuffer(buf) {
  if (!ArrayBufferIsView(buf)) {
    throw new ERR_INVALID_ARG_TYPE(
      "buf",
      ["Buffer", "TypedArray", "DataView"],
      buf,

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Use one of the supported names: 'utf8', 'utf16le', 'latin1', 'ascii', 'base64', 'base64url', 'hex'
  2. For any other encoding, use TextDecoder instead of StringDecoder
  3. Normalize config values before constructing: trim, lowercase, and map aliases through a whitelist

Example fix

// before
const dec = new StringDecoder(process.env.ENC || 'raw');
// ERR_UNKNOWN_ENCODING

// after
const dec = new StringDecoder('utf8');
// or, for wide encoding support:
const td = new TextDecoder('shift-jis');
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = new Set([
  'utf8', 'utf16le', 'latin1', 'ascii', 'base64', 'base64url', 'hex',
]);
const enc = String(rawEnc ?? 'utf8').trim().toLowerCase();
if (!SUPPORTED.has(enc)) {
  throw new TypeError(`unsupported StringDecoder encoding: ${enc}`);
}
const dec = new StringDecoder(enc);

Type guard

const isSupportedEncoding = (e) =>
  ['utf8', 'utf16le', 'latin1', 'ascii', 'base64', 'base64url', 'hex'].includes(e);

Prevention

When it happens

Trigger: `new StringDecoder('raw')`, `new StringDecoder('unicode')`, `new StringDecoder('utf-8x')`, or constructing with a null/undefined-ish value that fails casting and is not the exact string 'raw' (which also throws).

Common situations: Encoding names loaded from config/env with unsupported IANA or Windows labels ('unicode', 'cp1252'); code ported from TextDecoder which accepts far more labels (e.g. 'shift-jis'); older code relying on 'binary' spellings that were removed or on 'raw' semantics.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/db2e9d4cffd17ba9. Report an issue: GitHub.