pxb1988/dex2jar · error · ZipException
End Of Central Directory signature not found
Error message
End Of Central Directory signature not found
What it means
ZipFile.readCentralDir scans backwards from the end of the file looking for the End Of Central Directory signature (0x06054b50). If it is not found before reaching the start of the plausible scan area, the file is not a valid (non-truncated) zip and ZipException is thrown.
Solutions
- Verify the input is a real zip (magic PK) before opening
- Re-download/rebuild the archive
- Strip leading prepended data or repair the EOCD if appending was the cause
Example fix
// before
ZipFile zip = new ZipFile(new RandomAccessFile(path, "r"));
// after
byte[] head = new byte[4];
try (FileInputStream in = new FileInputStream(path)) { in.read(head); }
if (head[0] != 'P' || head[1] != 'K') throw new IOException("not a zip file: " + path);
ZipFile zip = new ZipFile(new RandomAccessFile(path, "r")); Defensive patterns
Strategy: try-catch
Validate before calling
byte[] tail = readLastBytes(path, 22); boolean hasEocd = tail[tail.length-22] == 0x50 && tail[tail.length-21] == 0x4B && tail[tail.length-20] == 0x05 && tail[tail.length-19] == 0x06;
Type guard
boolean hasEocdSignature(byte[] tail) { return tail.length >= 4 && tail[tail.length-22] == 'P' && tail[tail.length-21] == 'K' && tail[tail.length-20] == 5 && tail[tail.length-19] == 6; } Try / catch
try { ZipFile z = new ZipFile(f); } catch (ZipException e) { if (e.getMessage().contains("End Of Central Directory")) throw new IOException("corrupt or non-zip file"); throw e; } Prevention
- Verify the EOCD signature near the end of the file before opening
- Avoid appending/prepending bytes to zips (breaks EOCD position assumptions)
- Re-download archives with checksum verification
When it happens
Trigger: Opening files that are not zip archives, zips with corrupted/truncated EOCD, or self-extracting/odd formats where the EOCD is beyond the search stop offset.
Common situations: Pointing dex tooling at an APK that is actually a plain file, corrupted downloads, prepended data (e.g. self-extracting stubs) breaking EOCD search assumptions.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- File too short to be a zip file:
- signature not found; was
- File too small to be a dex/zip
- Can not find classes.dex in zip file
- File too small to be a dex/zip
AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08).
Data as JSON: /api/errors/83854c1efe7ce02a.
Report an issue: GitHub.
Appendix: source
Thrown at dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java:216
// final int headerMagic = raf.getInt();
// if (headerMagic != LOCSIG) {
// throw new ZipException("Not a zip archive");
// }
long stopOffset = scanOffset - 65536;
if (stopOffset < 0) {
stopOffset = 0;
}
while (true) {
raf.position((int) scanOffset);
if (raf.getInt() == ENDSIG) {
break;
}
scanOffset--;
if (scanOffset < stopOffset) {
throw new ZipException("End Of Central Directory signature not found");
}
}
// Read the End Of Central Directory. ENDHDR includes the signature bytes,
// which we've already read.
// Pull out the information we need.
int diskNumber = raf.getShort() & 0xffff;
int diskWithCentralDir = raf.getShort() & 0xffff;
int numEntries = raf.getShort() & 0xffff;
int totalNumEntries = raf.getShort() & 0xffff;
skip(raf, 4); // Ignore centralDirSize.
long centralDirOffset = ((long) raf.getInt()) & 0xffffffffL;
int commentLength = raf.getShort() & 0xffff;
if (numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0) {
throw new ZipException("Spanned archives not supported");
}View on GitHub (pinned to b5bda4fb49)