prestodb/presto · critical · PrestoException
DRUID_SEGMENT_LOAD_ERROR
DRUID_SEGMENT_LOAD_ERROR
Error message
Malformed End of Central Directory Record; does not start with %08x
What it means
Zip64EndOfCentralDirectory.read validates the ZIP64 EOCD locator target starts with the ZIP64 EOCD signature 0x06064b50. When the bytes at the given offset are not that signature, the ZIP64 end-of-central-directory structure is missing or corrupt and DRUID_SEGMENT_LOAD_ERROR is thrown.
Source
Thrown at presto-druid/src/main/java/com/facebook/presto/druid/zip/Zip64EndOfCentralDirectory.java:48
static final int CD_OFFSET_OFFSET = 48;
private Zip64EndOfCentralDirectory()
{
}
/**
* Read the Zip64 end of central directory record from the input stream and parse additional
* {@link ZipFileData} from it.
*/
public static void read(ZipFileData file, DataInputSource dataInputSource, long offset)
throws IOException
{
checkArgument(file != null, "Zip file data for source:%s is null", dataInputSource.getId());
byte[] fixedSizeData = new byte[FIXED_DATA_SIZE];
dataInputSource.readFully(offset, fixedSizeData);
if (!ZipUtil.arrayStartsWith(fixedSizeData, ZipUtil.intToLittleEndian(SIGNATURE))) {
throw new PrestoException(DRUID_SEGMENT_LOAD_ERROR, format("Malformed End of Central Directory Record; does not start with %08x", SIGNATURE));
}
file.setZip64(true);
file.setCentralDirectoryOffset(ZipUtil.getUnsignedLong(fixedSizeData, CD_OFFSET_OFFSET));
file.setExpectedEntries(ZipUtil.getUnsignedLong(fixedSizeData, TOTAL_ENTRIES_OFFSET));
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Re-create the segment zip with a ZIP64-capable standard tool (zip -64 / java.util.zip with ZIP64) and re-upload.
- Verify the large archive's integrity end-to-end (checksum before/after upload).
- Reduce archive size or entry count below ZIP64 thresholds if the producing pipeline mishandles ZIP64.
- Confirm the deep-storage object wasn't truncated by a proxy with a size limit.
Example fix
// before: streaming write that may omit ZIP64 zipOut.putNextEntry(hugeEntry); // after: ensure ZIP64 mode / precomputed sizes zipOut.setUseZip64(Zip64Mode.Always); entry.setSize(precomputedSize); zipOut.putNextEntry(hugeEntry);
Defensive patterns
Strategy: validation
Validate before calling
if (entryCount > 0xFFFF || totalSize > 0xFFFFFFFFL) {
verifyZip64StructuresPresent(archiveBytes); // locator + ZIP64 EOCD signature 0x06064b50
} Try / catch
try {
zip64Eocd = Zip64EndOfCentralDirectory.read(source, offset);
} catch (PrestoException e) {
log.error("Missing/corrupt ZIP64 EOCD for %s", source.getId(), e);
rebuildAndReuploadSegment(segmentId);
} Prevention
- Always build large archives with ZIP64 enabled end-to-end.
- Verify multi-GB uploads with checksums; watch for proxy size limits.
- Test producing pipelines with >4GB archives before production use.
When it happens
Trigger: read() on a file whose Zip64 EOCD record offset (from the locator or EOCD fields) points at data that does not start with the ZIP64 signature — typically a very large archive (>4GB / >65535 entries) whose ZIP64 structures were truncated or written incorrectly.
Common situations: Huge Druid segment zips created or transferred by tools that drop/rewrite ZIP64 extensions, truncated multi-gigabyte uploads, or archives created with streaming writers that emit incorrect ZIP64 offsets.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- DRUID_SEGMENT_LOAD_ERROR
- DRUID_SEGMENT_LOAD_ERROR
- DRUID_SEGMENT_LOAD_ERROR
- DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION
- DRUID_BROKER_RESULT_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/3d5264e2e91dfeb6.
Report an issue: GitHub.