gchq/CyberChef · error · OperationError

Unhandled Charset

Error message

Unhandled Charset

What it means

Thrown by the MIME Decoding operation when an RFC 2047 encoded word specifies a charset that convertFromCharset() does not support. Only UTF-8, US-ASCII, and ISO-8859-1 through ISO-8859-16 are handled; any other charset token (or an ISO-8859 part number outside 1–16) reaches the final throw at MIMEDecoding.mjs:137. The charset string is lower-cased and split on '-' before matching.

Source

Thrown at src/core/operations/MIMEDecoding.mjs:137

     *
     * @param encodedWord
     */
    convertFromCharset(charset, encodedText) {
        charset = charset.toLowerCase();
        const parsedCharset = charset.split("-");

        if (parsedCharset.length === 2 && parsedCharset[0] === "utf" && charset === "utf-8") {
            return cptable.utils.decode(65001, encodedText);
        } else if (parsedCharset.length === 2 && charset === "us-ascii") {
            return cptable.utils.decode(20127, encodedText);
        } else if (parsedCharset.length === 3 && parsedCharset[0] === "iso" && parsedCharset[1] === "8859") {
            const isoCharset = parseInt(parsedCharset[2], 10);
            if (isoCharset >= 1 && isoCharset <= 16) {
                return cptable.utils.decode(28590 + isoCharset, encodedText);
            }
        }

        throw new OperationError("Unhandled Charset");
    }

    /**
     * Parses a Q encoded word
     *
     * @param encodedWord
     */
    parseQEncodedWord(encodedWord) {
        let decodedWord = "";
        for (let i = 0; i < encodedWord.length; i++) {
            if (encodedWord[i] === "_") {
                decodedWord += " ";
            // Parse hex encoding
            } else if (encodedWord[i] === "=") {
                if ((i + 2) >= encodedWord.length) throw new OperationError("Incorrectly Encoded Word");
                const decodedHex = Utils.byteArrayToChars(fromHex(encodedWord.substring(i + 1, i + 3)));
                decodedWord += decodedHex;
                i += 2;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Pre-convert the header to a supported charset (UTF-8, US-ASCII, or ISO-8859-1..16) before feeding it to MIME Decoding.
  2. If you only need the raw bytes, strip the charset from the encoded-word marker or use a different decoding operation.
  3. For windows-1252 content, map it to the closest ISO-8859-1 token (lossy for the 0x80-0x9F range) or decode it manually.
  4. Request charset support be added, or fall back to an external library for unsupported charsets.

Example fix

// before — unsupported charset in header
// =?windows-1252?Q?Test=92s?=
mimeDecoding.run(bytes, []);   // throws 'Unhandled Charset'

// after — normalise charset to a supported one first
const text = Utils.byteArrayToUtf8(bytes)
  .replace(/=\?windows-1252\?/gi, '=?ISO-8859-1?');
mimeDecoding.run(Utils.strToByteArray(text), []);
Defensive patterns

Strategy: fallback

Validate before calling

const SUPPORTED = /^utf-8$|^us-ascii$|^iso-8859-(1[0-6]|[1-9])$/i;
function supportedCharset(cs) {
  return SUPPORTED.test(String(cs).toLowerCase().trim());
}
// before decoding, normalise or reject unsupported charsets
if (!supportedCharset(charset)) {
  // e.g. rewrite windows-1252 -> ISO-8859-1, or skip the encoded word
}

Type guard

const SUPPORTED_CHARSET = /^utf-8$|^us-ascii$|^iso-8859-(1[0-6]|[1-9])$/i;
function isSupportedCharset(v: unknown): v is string {
  return typeof v === 'string' && SUPPORTED_CHARSET.test(v.toLowerCase().trim());
}

Try / catch

try {
  mimeDecoding.run(bytes, []);
} catch (e) {
  if (e instanceof OperationError && /Unhandled Charset/.test(e.message)) {
    // fall back: normalise charset to ISO-8859-1/UTF-8 and retry, or return raw text
  } else throw e;
}

Prevention

When it happens

Trigger: Decoding a MIME header whose encoded word uses an unsupported charset, e.g. =?windows-1252?Q?...?=, =?ISO-8859-17?Q?...?= (part 17 is out of range), =?Shift_JIS?B?...?=, =?KOI8-R?Q?...?=. Raised at MIMEDecoding.mjs:137 inside convertFromCharset, called from decodeHeaders.

Common situations: Mail from Windows clients using windows-1252; Asian-language headers (ISO-2022-JP, Shift_JIS, EUC-KR); Russian/Eastern-European charsets (KOI8-R, CP1251); an ISO-8859 variant beyond part 16.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/44756b6ebfcc8658. Report an issue: GitHub.