pxb1988/dex2jar · error · IOException
Error reading data for near offset
Error message
Error reading data for near offset
What it means
Thrown by the ZipEntryInputStream.read() wrapper in dex-reader's bundled zip implementation. When the underlying inflater stream (super.read) throws an IOException while decompressing a zip entry, it is re-wrapped as 'Error reading data for <entryName> near offset <bytesRead>', preserving the entry name and bytes read so far plus the original cause.
Solutions
- Verify archive integrity (zip -t / unzip -t) and re-obtain the file; the deflate stream is corrupt at that offset.
- Inspect IOException.getCause() to distinguish zip format corruption from file I/O errors.
- When processing untrusted archives, catch this IOException per entry and skip the bad entry instead of aborting the whole file.
- Ensure the ZipFile's backing file is not truncated or closed while being read.
Example fix
// before
try (InputStream in = zipFile.getInputStream(entry)) {
byte[] data = in.readAllBytes(); // throws on corrupt entry
}
// after
try (InputStream in = zipFile.getInputStream(entry)) {
byte[] data = in.readAllBytes();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Error reading data for")) {
logger.warn("Skipping corrupt zip entry", e);
} else {
throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check archive integrity before opening with ZipFile
Process p = new ProcessBuilder("unzip", "-t", archivePath).redirectErrorStream(true).start();
if (p.waitFor() != 0) throw new IllegalStateException("Archive corrupt: " + archivePath);
Type guard
// Java has no type guards; validate entry metadata before reading
static boolean isReadableEntry(ZipEntry e) {
return e != null && !e.isDirectory() && e.getSize() >= 0;
}
Try / catch
try (InputStream in = zipFile.getInputStream(entry)) {
in.transferTo(out);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Error reading data for")) {
logger.warn("Corrupt zip entry skipped (offset info in message)", e);
} else {
throw e;
}
}
Prevention
- Verify downloaded archives via checksum or unzip -t before parsing.
- Catch IOException per entry so one bad entry does not abort whole-archive processing.
- Inspect getCause() to distinguish format corruption from file I/O faults.
- Never truncate or modify the archive while a ZipFile is open on it.
When it happens
Trigger: Calling ZipFile.getInputStream(entry).read(...) where the underlying stream read throws: corrupt or truncated deflate data, mismatched CRC/compression metadata, or an I/O fault reading the backing file mid-entry.
Common situations: Reading a corrupted, partially downloaded, or maliciously crafted .apk/.jar archive; archives modified after the central directory was written; disk/network faults while the archive is streamed.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Size mismatch on inflated file: vs
- cant find zipfs support
- 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/eed008b4e5397d2e.
Report an issue: GitHub.
Appendix: source
Thrown at dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java:295
}
}
static class ZipInflaterInputStream extends InflaterInputStream {
private final ZipEntry entry;
private long bytesRead = 0;
public ZipInflaterInputStream(InputStream is, Inflater inf, int bsize, ZipEntry entry) {
super(is, inf, bsize);
this.entry = entry;
}
@Override
public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException {
final int i;
try {
i = super.read(buffer, byteOffset, byteCount);
} catch (IOException e) {
throw new IOException("Error reading data for " + entry.getName() + " near offset " + bytesRead, e);
}
if (i == -1) {
if (entry.size != bytesRead) {
throw new IOException("Size mismatch on inflated file: " + bytesRead + " vs " + entry.size);
}
} else {
bytesRead += i;
}
return i;
}
@Override
public int available() throws IOException {
return super.available() == 0 ? 0 : (int) (entry.getSize() - bytesRead);
}
}
private static class ByteBufferBackedInputStream extends InputStream {View on GitHub (pinned to b5bda4fb49)