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
- Pre-convert the header to a supported charset (UTF-8, US-ASCII, or ISO-8859-1..16) before feeding it to MIME Decoding.
- If you only need the raw bytes, strip the charset from the encoded-word marker or use a different decoding operation.
- For windows-1252 content, map it to the closest ISO-8859-1 token (lossy for the 0x80-0x9F range) or decode it manually.
- 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
- Pre-rewrite uncommon charsets (windows-1252, KOI8-R, Shift_JIS) to UTF-8 before decoding.
- Detect unsupported encoded-words and strip or replace them.
- Maintain a charset allow-list matching the op's coverage (UTF-8, US-ASCII, ISO-8859-1..16).
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
- Incorrectly Encoded Word
- Invalid Base64 alphabet length (${alphabet.length}): ${alpha
- Byte length must be a positive integer
- unexpected character encountered: "${character}"
- Invalid encoding
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/44756b6ebfcc8658.
Report an issue: GitHub.