MuntashirAkon/AppManager · error · IOException
Corrupted struct sparse detected
Error message
Corrupted struct sparse detected
What it means
Thrown by TarArchiveInputStream.buildSparseInputStreams when a GNU/pax sparse-file header lists a chunk whose offset is less than the current stream offset, meaning the sparse entries are not monotonically increasing. This indicates the archive's sparse metadata is corrupt, so the library refuses to build the sparse input stream list rather than produce a wrongly reassembled file.
Source
Thrown at app/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java:923
final Comparator<TarArchiveStructSparse> sparseHeaderComparator = (p, q) -> {
final Long pOffset = p.getOffset();
final Long qOffset = q.getOffset();
return pOffset.compareTo(qOffset);
};
Collections.sort(sparseHeaders, sparseHeaderComparator);
}
if (sparseHeaders != null) {
// Stream doesn't need to be closed at all as it doesn't use any resources
final InputStream zeroInputStream = new TarArchiveSparseZeroInputStream(); //NOSONAR
long offset = 0;
for (final TarArchiveStructSparse sparseHeader : sparseHeaders) {
if (sparseHeader.getOffset() == 0 && sparseHeader.getNumbytes() == 0) {
break;
}
if ((sparseHeader.getOffset() - offset) < 0) {
throw new IOException("Corrupted struct sparse detected");
}
// only store the input streams with non-zero size
if ((sparseHeader.getOffset() - offset) > 0) {
sparseInputStreams.add(new BoundedInputStream(zeroInputStream, sparseHeader.getOffset() - offset));
}
// only store the input streams with non-zero size
if (sparseHeader.getNumbytes() > 0) {
sparseInputStreams.add(new BoundedInputStream(inputStream, sparseHeader.getNumbytes()));
}
offset = sparseHeader.getOffset() + sparseHeader.getNumbytes();
}
}
if (!sparseInputStreams.isEmpty()) {
currentSparseInputStreamIndex = 0;View on GitHub (pinned to 0152f468fc)
Solutions
- Verify the archive integrity (checksum, re-download) — the file itself is likely corrupt.
- Re-create the archive with a standard tool (GNU tar with -S for sparse files) instead of hand-building sparse headers.
- If you control archive generation, ensure sparse offsets are strictly increasing and cover the file contiguously.
- If you don't need sparse support, write the archive as a normal (non-sparse) tar entry.
Example fix
// before: trusting a third-party sparse tar
ew TarArchiveInputStream(new FileInputStream(f)) // throws on corrupt sparse headers
// after: validate source first
if (!checksumMatches(f, expectedSha256)) throw new IOException("archive corrupt, re-fetch"); Defensive patterns
Strategy: validation
Validate before calling
// Before reading a sparse entry, sanity-check each sparse header
for (TarArchiveStructSparse s : sparseHeaders) {
if (s.getOffset() < lastOffset) throw new IOException("non-monotonic sparse offset: " + s.getOffset());
lastOffset = s.getOffset() + s.getNumbytes();
} Try / catch
try (TarArchiveInputStream tis = new TarArchiveInputStream(in)) {
// read entries
} catch (IOException e) {
if (e.getMessage().contains("Corrupted struct sparse")) {
// quarantine/re-fetch archive
} else throw e;
} Prevention
- Verify archive checksums before extraction
- Re-download truncated archives instead of retrying
- Avoid hand-editing tar headers
- Use GNU tar -S to create valid sparse archives
When it happens
Trigger: Reading a tar entry whose pax or old-GNU sparse headers (via paxHeaders or readOldGNUSparse) contain a sparse struct whose offset is smaller than the previous chunk's offset+size; typically a truncated, hand-edited, or maliciously crafted archive.
Common situations: Processing untrusted or partially downloaded tar archives; archives transferred in text mode corrupting header bytes; hand-crafted sparse entries; fuzzed/security-scanned inputs (this check exists as a hardening against crafted archives).
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- APK files backup is requested but no source directory has be
- Failed to backup data directory at
- Could not backup KeyStore item.
- Failed to extract the apk file(s).
- Failed to restore data files for index ${index}.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/4504dfc2249474fa.
Report an issue: GitHub.