MuntashirAkon/AppManager · error · IOException

Error detected parsing the pax header

Error message

Error detected parsing the pax header

What it means

Wraps a NumberFormatException raised while processing PAX extended header entries in getNextTarEntry. A PAX header record's numeric value (e.g. size, devmajor/devminor, or a GNU sparse field) was not a valid number, so the stream fails with an IOException identifying the PAX header as the culprit.

Solutions

  1. Re-create the archive with a compliant tool (GNU tar with --format=pax or --format=gnu)
  2. Check that the archive wasn't modified after creation (compare hashes)
  3. Avoid text-editing/normalizing archive files in transit
  4. Catch IOException around getNextTarEntry and surface a corrupt-archive message

Example fix

// before
while ((entry = tarIn.getNextTarEntry()) != null) { ... }
// after
try {
    while ((entry = tarIn.getNextTarEntry()) != null) { ... }
} catch (IOException e) {
    throw new IOException("Failed reading PAX header entry", e);
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    TarArchiveEntry e = tarIn.getNextTarEntry();
} catch (IOException e) {
    if (e.getCause() instanceof NumberFormatException) {
        throw new IOException("Malformed PAX header in archive", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: getNextTarEntry() (via getNextEntry()) encounters an entry flagged as a PAX header whose key=value records contain non-numeric values where numbers are required (bad 'size', 'GNU.sparse.*' fields).

Common situations: Archives edited or truncated by text-based tools (PAX headers are plain text, so editors can mangle them); archives from non-compliant tar implementations.

Related errors


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

Appendix: source

Thrown at app/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java:413

            final String name = zipEncoding.decode(longNameData);
            currEntry.setName(name);
            if (currEntry.isDirectory() && !name.endsWith("/")) {
                currEntry.setName(name + "/");
            }
        }

        if (currEntry.isGlobalPaxHeader()){ // Process Global Pax headers
            readGlobalPaxHeaders();
        }

        try {
            if (currEntry.isPaxHeader()){ // Process Pax headers
                paxHeaders();
            } else if (!globalPaxHeaders.isEmpty()) {
                applyPaxHeadersToCurrentEntry(globalPaxHeaders, globalSparseHeaders);
            }
        } catch (final NumberFormatException e) {
            throw new IOException("Error detected parsing the pax header", e);
        }

        if (currEntry.isOldGNUSparse()){ // Process sparse files
            readOldGNUSparse();
        }

        // If the size of the next element in the archive has changed
        // due to a new size being reported in the posix header
        // information, we update entrySize here so that it contains
        // the correct value.
        entrySize = currEntry.getSize();

        return currEntry;
    }

    /**
     * The last record block should be written at the full size, so skip any
     * additional space used to fill a record after an entry.

View on GitHub (pinned to 0152f468fc)