gchq/CyberChef · error · OperationError

Input does not appear to be a PDF file.

Error message

Input does not appear to be a PDF file.

What it means

Thrown by RenderPDF.run when the first four bytes of the input are not the PDF signature '%PDF' (0x25 0x50 0x44 0x46). CyberChef does not deeply parse the file; it only checks the magic bytes before passing data to the renderer.

Source

Thrown at src/core/operations/RenderPDF.mjs:77

        // Convert input to raw bytes
        switch (inputFormat) {
            case "Base64":
                input = fromBase64(input, undefined, "byteArray");
                break;
            case "Raw":
            default:
                input = Utils.strToByteArray(input);
                break;
        }

        // Check PDF signature
        if (
            input[0] !== 0x25 || // %
            input[1] !== 0x50 || // P
            input[2] !== 0x44 || // D
            input[3] !== 0x46    // F
        ) {
            throw new OperationError("Input does not appear to be a PDF file.");
        }

        return input;
    }

    /**
     * Displays the PDF using HTML for web apps.
     *
     * @param {byteArray} data
     * @returns {html}
     */
    async present(data) {
        if (!data.length) return "";

        const base64 = toBase64(data);
        const dataURI = "data:application/pdf;base64," + base64;

        return `<iframe src="${dataURI}" style="width:100%;height:100%;border:1px solid #ccc;"></iframe>`;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Confirm the file begins with bytes 25 50 44 46 ('%PDF').
  2. Set the input format to 'Base64' if the data is still encoded.
  3. Strip leading whitespace/BOM so %PDF is at offset 0.
  4. Re-download a complete, uncorrupted PDF.

Example fix

// before
//   input: base64 text 'JVBERi0...' with format Raw -> first byte 'J' != 0x25
// after
//   input format: Base64  (decodes to %PDF...)
Defensive patterns

Strategy: validation

Validate before calling

if (input[0]!==0x25||input[1]!==0x50||input[2]!==0x44||input[3]!==0x46) throw new Error('Not a PDF (missing %PDF header)');

Type guard

const isPdf = b => b.length>=4 && b[0]===0x25 && b[1]===0x50 && b[2]===0x44 && b[3]===0x46;

Try / catch

try { renderPdf(input); } catch (e) { if (/PDF file/.test(e.message)) decodeOrRedownload(); else throw e; }

Prevention

When it happens

Trigger: Input that is not a PDF; a PDF whose header is preceded by leading whitespace/BOM bytes; Base64 input decoded with the wrong format option; truncated file missing the header.

Common situations: Feeding a Word/image/HTML file; pasting Base64 without setting the format to Base64; files with a leading BOM or garbage before %PDF; corrupted downloads.

Related errors


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