prestodb/presto · error · OrcCorruptionException

Not an ORC file

Error message

Not an ORC file

What it means

When parsing the PostScript fails with OrcCorruptionException, the library checks the file's leading magic bytes. If the header is not the valid 'ORC' magic, it rethrows a clearer 'Not an ORC file' error instead of the low-level parse failure. This indicates the data source is not ORC format at all.

Source

Thrown at presto-orc/src/main/java/com/facebook/presto/orc/cache/StorageOrcFileTailSource.java:93

        // Read the tail of the file
        byte[] buffer = new byte[toIntExact(min(size, expectedFooterSizeInBytes))];
        orcDataSource.readFully(size - buffer.length, buffer);

        // get length of PostScript - last byte of the file
        int postScriptSize = buffer[buffer.length - SIZE_OF_BYTE] & 0xff;
        if (postScriptSize >= buffer.length) {
            throw new OrcCorruptionException(orcDataSource.getId(), "Invalid postscript length %s", postScriptSize);
        }

        // decode the post script
        PostScript postScript;
        try {
            postScript = metadataReader.readPostScript(buffer, buffer.length - SIZE_OF_BYTE - postScriptSize, postScriptSize);
        }
        catch (OrcCorruptionException e) {
            // check if this is an ORC file and not an RCFile or something else
            if (!isValidHeaderMagic(orcDataSource)) {
                throw new OrcCorruptionException(orcDataSource.getId(), "Not an ORC file");
            }
            throw e;
        }

        // verify this is a supported version
        checkOrcVersion(orcDataSource, postScript.getVersion());
        validateWrite(writeValidation, orcDataSource, validation -> validation.getVersion().equals(postScript.getVersion()), "Unexpected version");

        int bufferSize = toIntExact(postScript.getCompressionBlockSize());

        // check compression codec is supported
        CompressionKind compressionKind = postScript.getCompression();
        validateWrite(writeValidation, orcDataSource, validation -> validation.getCompression() == compressionKind, "Unexpected compression");

        PostScript.HiveWriterVersion hiveWriterVersion = postScript.getHiveWriterVersion();

        int footerSize = toIntExact(postScript.getFooterLength());
        int metadataSize = toIntExact(postScript.getMetadataLength());

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Confirm the file format (file command / first 3 bytes) and use the matching reader for Parquet, Avro, RCFile, etc.
  2. Fix the table/connector format configuration so the path points to ORC output.
  3. Re-run the job that was supposed to produce ORC output; the file may be a leftover from a different format.
  4. If the file was converted in-place, restore the original ORC version.

Example fix

// before
SchemaTableName table = new SchemaTableName("sales", "events"); // hive table with format=RCFILE but query expects ORC
// after
ALTER TABLE sales.events SET FILEFORMAT ORC; -- or point query at the correct ORC table
Defensive patterns

Strategy: validation

Validate before calling

byte[] magic = new byte[3];
orcDataSource.readFully(0, magic);
if (!Arrays.equals(magic, "ORC".getBytes(StandardCharsets.US_ASCII))) {
    throw new SkipFileException("Not an ORC file: " + orcDataSource.getId());
}

Try / catch

try { tail = source.getOrcFileTail(ds, reader, Optional.empty(), false, time); }
catch (OrcCorruptionException e) {
    // e.getMessage() contains "Not an ORC file" -> route to correct format reader
}

Prevention

When it happens

Trigger: metadataReader.readPostScript throws inside getOrcFileTail and isValidHeaderMagic(orcDataSource) returns false — i.e. the first bytes are not the ORC magic.

Common situations: Pointing a connector at RCFiles, Avro, Parquet, sequence files, or text data; reading a directory listing placeholder; a file renamed/symlinked incorrectly.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/30f4253ed8384e5d. Report an issue: GitHub.