{"record":{"id":"8649e5defd705436","repo":"prestodb/presto","slug":"druid-segment-load-error-8649e5","errorCode":"DRUID_SEGMENT_LOAD_ERROR","errorMessage":"Malformed Central Directory File Header; does not start with %08x","messagePattern":"Malformed Central Directory File Header; does not start with %08x","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"critical","filePath":"presto-druid/src/main/java/com/facebook/presto/druid/zip/CentralDirectoryFileHeader.java","lineNumber":57,"sourceCode":"    static final int INTERNAL_ATTRIBUTES_OFFSET = 36;\n    static final int EXTERNAL_ATTRIBUTES_OFFSET = 38;\n    static final int LOCAL_HEADER_OFFSET_OFFSET = 42;\n\n    private CentralDirectoryFileHeader()\n    {\n    }\n\n    // read one ZipFileEntry and add into ZipFileData\n    public static long read(ZipFileData fileData, DataInputSource dataInputSource, long fileOffset, Charset charset)\n            throws IOException\n    {\n        long position = fileOffset;\n\n        byte[] fixedSizeData = new byte[FIXED_DATA_SIZE];\n        dataInputSource.readFully(position, fixedSizeData);\n        position += fixedSizeData.length;\n        if (!ZipUtil.arrayStartsWith(fixedSizeData, ZipUtil.intToLittleEndian(SIGNATURE))) {\n            throw new PrestoException(DRUID_SEGMENT_LOAD_ERROR, String.format(\"Malformed Central Directory File Header; does not start with %08x\", SIGNATURE));\n        }\n\n        byte[] name = new byte[ZipUtil.getUnsignedShort(fixedSizeData, FILENAME_LENGTH_OFFSET)];\n        byte[] extraField = new byte[ZipUtil.getUnsignedShort(fixedSizeData, EXTRA_FIELD_LENGTH_OFFSET)];\n        byte[] comment = new byte[ZipUtil.getUnsignedShort(fixedSizeData, COMMENT_LENGTH_OFFSET)];\n\n        if (name.length > 0) {\n            dataInputSource.readFully(position, name);\n            position += name.length;\n        }\n        if (extraField.length > 0) {\n            dataInputSource.readFully(position, extraField);\n            position += extraField.length;\n        }\n        if (comment.length > 0) {\n            dataInputSource.readFully(position, comment);\n            position += extraField.length;\n        }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-druid/src/main/java/com/facebook/presto/druid/zip/CentralDirectoryFileHeader.java#L39-L75","documentation":"CentralDirectoryFileHeader.read verifies each central directory entry starts with the signature 0x02014b50. When the bytes at the expected entry offset do not match, the central directory is out of sync with the actual file layout, and DRUID_SEGMENT_LOAD_ERROR is thrown.","triggerScenarios":"read() called by bytesRead for an entry at fileOffset whose fixed-size data does not begin with SIGNATURE — i.e., the offset/count derived from the EOCD is wrong or the directory region is corrupted.","commonSituations":"Corrupted/truncated zips where the EOCD points at the wrong central directory offset (wrong offsets stored by a buggy writer), files modified in place after upload, or non-zip data whose tail coincidentally contains an EOCD-looking signature.","solutions":["Re-upload/re-ingest the segment zip; the archive's central directory is corrupt.","Test the archive with `unzip -t` to confirm the corruption, and check the producing pipeline's writer version.","Ensure the file is byte-identical to what was uploaded (compare checksums between producer and deep storage).","If the zip was repaired by a third-party tool, rebuild it with a standard tool (zip/jar) instead."],"exampleFix":"// before: blind retry on corrupt segment\nsegmentLoader.load(location);\n// after: validate archive, then fall back to re-fetch\nif (!zipLooksValid(location)) {\n    location = reIngestSegment(segmentId);\n}\nsegmentLoader.load(location);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    centralDirectoryHeaders = readHeaders(source, eocd);\n} catch (PrestoException e) {\n    if (String.valueOf(e.getMessage()).contains(\"Malformed Central Directory File Header\")) {\n        handleCorruptSegment(segmentId);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Store checksums with segment metadata and verify before load.","Keep segment zips immutable after upload — never rewrite in place.","Build archives only with standard tools (zip/jar/java.util.zip)."],"tags":["zip","druid","central-directory","corrupt-file"],"backgroundTag":"malformed-zip-missing-eocd","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}