MuntashirAkon/AppManager · error · IOException

broken archive, entry with negative size

Error message

broken archive, entry with negative size

What it means

Thrown during tar header parsing when the size field of a header block decodes to a negative number. Tar sizes are octal (or base-256 binary), so a negative result means the header is corrupt — the parser refuses to continue rather than reading a wrong number of bytes.

Solutions

  1. Verify the archive's integrity (checksums, re-download, compare with the publisher's hash)
  2. Re-create the tar with GNU tar or bsdtar
  3. Confirm the file being parsed is actually an uncompressed tar (or wrap the stream in the right decompressor first)
  4. Catch IOException around header parsing and treat the archive as unreadable

Example fix

// before
TarArchiveEntry entry = new TarArchiveEntry(rawHeader, encoding);
// after
if (!TarUtils.verifyCheckSum(rawHeader)) {
    throw new IOException("corrupt tar header (checksum mismatch)");
}
TarArchiveEntry entry = new TarArchiveEntry(rawHeader, encoding);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!TarUtils.verifyCheckSum(header)) {
    throw new IOException("tar header checksum mismatch; archive corrupt");
}

Try / catch

try {
    TarArchiveEntry entry = new TarArchiveEntry(header, encoding);
} catch (IOException e) {
    // message contains 'negative size' for this case
    reportCorruptArchive(e);
}

Prevention

When it happens

Trigger: Constructing TarArchiveEntry from a raw 512-byte header whose size field is not valid octal and whose base-256 interpretation is negative — i.e. garbage or deliberately corrupted header bytes.

Common situations: Downloading archives over unreliable connections without checksums; archives modified in transit; files created by broken tar writers; random data mistakenly fed to a tar parser.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/bae294ba108d22ee. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java:1513

    }

    private void parseTarHeader(final byte[] header, final ZipEncoding encoding,
                                final boolean oldStyle, final boolean lenient)
            throws IOException {
        int offset = 0;

        name = oldStyle ? TarUtils.parseName(header, offset, NAMELEN)
                : TarUtils.parseName(header, offset, NAMELEN, encoding);
        offset += NAMELEN;
        mode = (int) parseOctalOrBinary(header, offset, MODELEN, lenient);
        offset += MODELEN;
        userId = (int) parseOctalOrBinary(header, offset, UIDLEN, lenient);
        offset += UIDLEN;
        groupId = (int) parseOctalOrBinary(header, offset, GIDLEN, lenient);
        offset += GIDLEN;
        size = TarUtils.parseOctalOrBinary(header, offset, SIZELEN);
        if (size < 0) {
            throw new IOException("broken archive, entry with negative size");
        }
        offset += SIZELEN;
        modTime = parseOctalOrBinary(header, offset, MODTIMELEN, lenient);
        offset += MODTIMELEN;
        checkSumOK = TarUtils.verifyCheckSum(header);
        offset += CHKSUMLEN;
        linkFlag = header[offset++];
        linkName = oldStyle ? TarUtils.parseName(header, offset, NAMELEN)
                : TarUtils.parseName(header, offset, NAMELEN, encoding);
        offset += NAMELEN;
        magic = TarUtils.parseName(header, offset, MAGICLEN);
        offset += MAGICLEN;
        version = TarUtils.parseName(header, offset, VERSIONLEN);
        offset += VERSIONLEN;
        userName = oldStyle ? TarUtils.parseName(header, offset, UNAMELEN)
                : TarUtils.parseName(header, offset, UNAMELEN, encoding);
        offset += UNAMELEN;
        groupName = oldStyle ? TarUtils.parseName(header, offset, GNAMELEN)

View on GitHub (pinned to 0152f468fc)