gchq/CyberChef · error · Error

Not a valid RTF file

Error message

Not a valid RTF file

What it means

Thrown by extractRTF when the first byte of the (offset-adjusted) stream is not 0x7B ('{'). RTF documents must begin with an opening brace (the real signature is '{\rtf'). A plain Error, not an OperationError, so it propagates as an internal failure.

Source

Thrown at src/core/lib/FileSignatures.mjs:3366

    return stream.carve();
}


/**
 * RTF extractor.
 *
 * @param {Uint8Array} bytes
 * @param {number} offset
 * @returns {Uint8Array}
 */
export function extractRTF(bytes, offset) {
    const stream = new Stream(bytes.slice(offset));

    let openTags = 0;

    if (stream.readInt(1) !== 0x7b) { // {
        throw new Error("Not a valid RTF file");
    } else {
        openTags++;
    }

    while (openTags > 0 && stream.hasMore()) {
        switch (stream.readInt(1)) {
            case 0x7b: // {
                openTags++;
                break;
            case 0x7d: // }
                openTags--;
                break;
            case 0x5c: // \
                // Consume any more escapes and then skip over the next character
                stream.consumeIf(0x5c);
                stream.position++;
                break;
            default:

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Confirm the data begins with '{' (ideally the full '{\rtf1' prolog).
  2. Strip any leading BOM or whitespace before extraction, or pass the correct offset.
  3. Route non-RTF input to the appropriate extractor.

Example fix

// before
extractRTF(bytesWithBom, 0);

// after
let off = 0;
if (bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf) off = 3;
extractRTF(bytes, off);
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeRTF(bytes, offset = 0) {
  return bytes.length - offset >= 1 && bytes[offset] === 0x7b; // '{'
}
if (!looksLikeRTF(bytes, offset)) throw new Error("Input is not RTF (does not start with '{')");
extractRTF(bytes, offset);

Type guard

const startsRTF = (bytes, offset = 0) => bytes[offset] === 0x7b;

Try / catch

try {
  extractRTF(bytes, offset);
} catch (err) {
  if (/Not a valid RTF file/.test(err.message)) {
    // route non-RTF input to the correct extractor
  } else throw err;
}

Prevention

When it happens

Trigger: Calling extractRTF on non-RTF data, on RTF preceded by a BOM or leading whitespace/bytes, or with an offset that skips the opening brace.

Common situations: Wrong file type routed to the RTF extractor; UTF-8/UTF-16 BOM before the '{'; plain text or HTML mistaken for RTF; offset misalignment.

Related errors


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