gchq/CyberChef · error · OperationError

Triplet too large: '${triple.join("")}'

Error message

Triplet too large: '${triple.join("")}'

What it means

Thrown by From Base45 when a decoded triplet value exceeds 65535, which cannot fit in the two output bytes Base45 expects per triplet. In valid Base45, a full triplet's combined value (after reversing and accumulating b*45+idx) must be <= 0xFFFF. Exceeding it indicates corrupted or non-Base45 input that survived character validation.

Source

Thrown at src/core/operations/FromBase45.mjs:78

        if (removeNonAlphChars) {
            const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
            input = input.replace(re, "");
        }

        for (const triple of Utils.chunked(input, 3)) {
            triple.reverse();
            let b = 0;
            for (const c of triple) {
                const idx = alphabet.indexOf(c);
                if (idx === -1) {
                    throw new OperationError(`Character not in alphabet: '${c}'`);
                }
                b *= 45;
                b += idx;
            }

            if (b > 65535) {
                throw new OperationError(`Triplet too large: '${triple.join("")}'`);
            }

            if (triple.length > 2) {
                /**
                 * The last triple may only have 2 bytes so we push the MSB when we got 3 bytes
                 * Pushing MSB
                 */
                res.push(b >> 8);
            }

            /**
             * Pushing LSB
             */
            res.push(b & 0xff);

        }

        return res;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Confirm the data is genuinely Base45 (e.g. from a QR code / EU DCC).
  2. If the data is another base, switch to the correct From Base operation.
  3. Re-encode or re-extract the source to ensure triplet integrity.

Example fix

// before: Base64-looking data fed as Base45
fromBase45.run(base64String, [ALPHABET, true]) // triplet overflows
// after: use the correct decoder
fromBase64.run(base64String, ...)
Defensive patterns

Strategy: validation

Validate before calling

// Heuristic: valid Base45 triplets decode to <= 65535; if you control the source,
// verify the input length is a multiple that aligns with Base45 grouping.
const alphabet = Utils.expandAlphRange(args[0]).join('');
// cannot fully pre-validate without decoding, but confirm input is the right encoding
if (!/^[0-9A-Z $%*+\-./:]+$/.test(input)) {
  // likely not Base45; choose another decoder
}

Try / catch

try {
  fromBase45.run(input, args);
} catch (e) {
  if (e.type === 'OperationError' && /Triplet too large/.test(e.message)) {
    // data is probably not Base45; try From Base58/64 instead
  } else throw e;
}

Prevention

When it happens

Trigger: Input that is structurally triplet-aligned and uses valid alphabet characters but whose values combine to > 65535 (e.g. three high-value chars); truncated/reordered Base45; data that looks like Base45 but is actually a different base with overlapping characters.

Common situations: Misidentified encoding (Base58/Base64 data fed as Base45); partially edited Base45 string; concatenation of two Base45 blobs without re-encoding.

Related errors


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