skylot/jadx · error · RuntimeException

Failed to open input stream for entry: {}

Error message

Failed to open input stream for entry: {}

What it means

Thrown by the fallback parser when merely opening an InputStream for an entry fails, before any bytes are read. getInputStream() delegates to getEntryStream(), which calls ZipFile.getInputStream() and optionally wraps it in a LimitedInputStream. Unlike getBytes() (which consumes the stream fully), this error means the stream could not be opened at all. The failing entry name is included and the cause is preserved.

Source

Thrown at jadx-commons/jadx-zip/src/main/java/jadx/zip/fallback/FallbackZipParser.java:86

		if (!validEntry) {
			LOG.warn("Zip entry '{}' is invalid and excluded from processing", zipEntry);
		}
		return validEntry;
	}

	public byte[] getBytes(FallbackZipEntry entry) {
		try (InputStream is = getEntryStream(entry)) {
			return is.readAllBytes();
		} catch (Exception e) {
			throw new RuntimeException("Failed to read bytes for entry: " + entry.getName(), e);
		}
	}

	public InputStream getInputStream(FallbackZipEntry entry) {
		try {
			return getEntryStream(entry);
		} catch (Exception e) {
			throw new RuntimeException("Failed to open input stream for entry: " + entry.getName(), e);
		}
	}

	private InputStream getEntryStream(FallbackZipEntry entry) throws IOException {
		InputStream entryStream = zipFile.getInputStream(entry.getZipEntry());
		InputStream stream;
		if (useLimitedDataStream) {
			stream = new LimitedInputStream(entryStream, entry.getUncompressedSize());
		} else {
			stream = entryStream;
		}
		return new BufferedInputStream(stream);
	}

	public File getZipFile() {
		return file;
	}

View on GitHub (pinned to e738a26571)

Solutions

  1. Inspect getCause() to distinguish a closed-zip error from a structural entry error.
  2. Ensure the ZipFile/ZipContent is not closed before all entry streams are consumed.
  3. Skip the entry in a try/catch and continue processing the rest of the archive.
  4. If every entry fails, the archive is structurally broken; obtain a fresh copy.

Example fix

// before
try (InputStream is = entry.getInputStream()) {
    return is.readAllBytes();
}

// after
try (InputStream is = entry.getInputStream()) {
    return is.readAllBytes();
} catch (RuntimeException e) {
    throw new IOException("Cannot stream entry " + entry.getName(), e.getCause());
}
Defensive patterns

Strategy: try-catch

Validate before calling

// No public 'isOpen()' probe exists; track zip lifecycle yourself.
// Ensure the owning ZipContent/ZipFile is open before requesting streams:
if (zipContent.isClosed()) {
    throw new IllegalStateException("Zip closed before streaming entry");
}

Try / catch

try (InputStream is = entry.getInputStream()) {
    return is.readAllBytes();
} catch (RuntimeException e) {
    throw new IOException("Cannot stream entry " + entry.getName(), e.getCause());
}

Prevention

When it happens

Trigger: Calling FallbackZipParser.getInputStream() (or IZipEntry.getInputStream() on a fallback entry) when ZipFile.getInputStream(entry) raises IOException because the entry's local header or data descriptor is malformed, the offset is out of range, or the entry was marked invalid after enumeration.

Common situations: Archive whose local file header offsets are inconsistent with the central directory; an entry referenced in the central directory but whose data is missing or truncated; zip produced by a buggy packer that jadx's fallback cannot stream; concurrent access where the ZipFile was already closed.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/7f00571c991787f7. Report an issue: GitHub.