{"record":{"id":"08fbd136bbc26ddb","repo":"prestodb/presto","slug":"invalid-postscript-length-s","errorCode":null,"errorMessage":"Invalid postscript length %s","messagePattern":"Invalid postscript length (.+?)","errorType":"exception","errorClass":"OrcCorruptionException","httpStatus":null,"severity":"error","filePath":"presto-orc/src/main/java/com/facebook/presto/orc/cache/StorageOrcFileTailSource.java","lineNumber":82,"sourceCode":"    }\n\n    @Override\n    public OrcFileTail getOrcFileTail(OrcDataSource orcDataSource, MetadataReader metadataReader, Optional<OrcWriteValidation> writeValidation, boolean cacheable, long fileModificationTime)\n            throws IOException\n    {\n        long size = orcDataSource.getSize();\n        if (size <= MAGIC.length()) {\n            throw new OrcCorruptionException(orcDataSource.getId(), \"Invalid file size %s\", size);\n        }\n\n        // Read the tail of the file\n        byte[] buffer = new byte[toIntExact(min(size, expectedFooterSizeInBytes))];\n        orcDataSource.readFully(size - buffer.length, buffer);\n\n        // get length of PostScript - last byte of the file\n        int postScriptSize = buffer[buffer.length - SIZE_OF_BYTE] & 0xff;\n        if (postScriptSize >= buffer.length) {\n            throw new OrcCorruptionException(orcDataSource.getId(), \"Invalid postscript length %s\", postScriptSize);\n        }\n\n        // decode the post script\n        PostScript postScript;\n        try {\n            postScript = metadataReader.readPostScript(buffer, buffer.length - SIZE_OF_BYTE - postScriptSize, postScriptSize);\n        }\n        catch (OrcCorruptionException e) {\n            // check if this is an ORC file and not an RCFile or something else\n            if (!isValidHeaderMagic(orcDataSource)) {\n                throw new OrcCorruptionException(orcDataSource.getId(), \"Not an ORC file\");\n            }\n            throw e;\n        }\n\n        // verify this is a supported version\n        checkOrcVersion(orcDataSource, postScript.getVersion());\n        validateWrite(writeValidation, orcDataSource, validation -> validation.getVersion().equals(postScript.getVersion()), \"Unexpected version\");","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-orc/src/main/java/com/facebook/presto/orc/cache/StorageOrcFileTailSource.java#L64-L100","documentation":"The last byte of an ORC/DWRF file encodes the length of the PostScript section. The library throws OrcCorruptionException when that byte value is >= the buffer size actually read, meaning the postscript cannot possibly fit inside the file tail — a sign of corruption or a non-ORC file.","triggerScenarios":"getOrcFileTail reads the last expectedFooterSizeInBytes bytes and the final byte (postScriptSize) is >= buffer.length; typical when the file is tiny, truncated mid-tail, or the 'footer size' byte region is garbage.","commonSituations":"Files truncated to fewer bytes than the real footer/postscript, files written by broken writers, or accidental reads of random binary/text files as ORC.","solutions":["Check file integrity (checksum/size against the writer's manifest) and re-fetch the file from source.","Confirm the file was written completely (look for a _SUCCESS/commit marker in the output directory).","Re-generate the file with the ORC writer; the tail bytes are unrecoverable if corrupt.","Ensure you are not reading a non-ORC file by mistake (check the 'ORC' magic header)."],"exampleFix":"// before\nbyte[] buffer = new byte[toIntExact(min(size, expectedFooterSizeInBytes))];\n// after\nbyte[] buffer = new byte[toIntExact(min(size, Math.max(expectedFooterSizeInBytes, OrcFile.Magic.length() + 1)))];\n// and validate size >= 4 before attempting read","handlingStrategy":"validation","validationCode":"long size = orcDataSource.getSize();\nif (size <= 3 || buffer[buffer.length - 1] >= buffer.length) {\n    throw new SkipFileException(\"Implausible postscript in \" + orcDataSource.getId());\n}","typeGuard":null,"tryCatchPattern":"try { tail = source.getOrcFileTail(ds, reader, validation, false, time); }\ncatch (OrcCorruptionException e) { quarantine(ds.getId(), e); }","preventionTips":["Verify file checksums after copy/download","Read only finalized files","Use orc-tools to sanity-check files in ingestion pipelines"],"tags":["orc","corrupt-file","postscript"],"backgroundTag":"orc-file-corruption","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}