MuntashirAkon/AppManager · error · IOException

Failed to read Paxheader.Value should end with a newline

Error message

Failed to read Paxheader.Value should end with a newline

What it means

Thrown by TarUtils.parsePaxHeaders when a PAX header value's last byte is not the required terminating newline ('\n'). The PAX format mandates each record end with LF; its absence means malformed or corrupted header data.

Solutions

  1. Fix the archive producer to terminate each PAX record value with '\n'
  2. Re-pack the archive using a standards-conforming tool (GNU tar, bsdtar)
  3. If hand-writing PAX headers, append newline after every value: len " key=value \n"
  4. Catch IOException and reject the archive as malformed

Example fix

// before (custom pax record writer)
out.write((record).getBytes(UTF_8)); // record lacks trailing \n
// after
out.write((record + "\n").getBytes(UTF_8));
Defensive patterns

Strategy: validation

Validate before calling

// when producing pax records yourself:
if (record.charAt(record.length() - 1) != '\n') {
    record = record + '\n';
}

Try / catch

try {
    // read tar
} catch (IOException e) {
    if (e.getMessage().contains("Value should end with a newline")) {
        throw new CorruptArchiveException("PAX header value missing LF terminator", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A PAX record whose value bytes were read fully but do not end with a newline; caused by hand-built PAX headers missing the trailing LF or corrupted data.

Common situations: Archives produced by non-conforming writers or string manipulation that trimmed the trailing newline (e.g. custom code doing trim() on header content), binary-transfer corruption.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at app/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java:725

                                headers.remove(keyword);
                            } else if (headerSize >= 0 && restLen > headerSize - totalRead) {
                                throw new IOException("Paxheader value size " + restLen
                                    + " exceeds size of header record");

                            } else {
                                final byte[] rest = new byte[restLen];
                                final int got = IOUtils.readFully(inputStream, rest);
                                if (got != restLen) {
                                    throw new IOException("Failed to read "
                                            + "Paxheader. Expected "
                                            + restLen
                                            + " bytes, read "
                                            + got);
                                }
                                totalRead += restLen;
                                // Drop trailing NL
                                if (rest[restLen - 1] != '\n') {
                                    throw new IOException("Failed to read Paxheader."
                                       + "Value should end with a newline");
                                }
                                final String value = new String(rest, 0,
                                        restLen - 1, StandardCharsets.UTF_8);
                                headers.put(keyword, value);

                                // for 0.0 PAX Headers
                                if (keyword.equals("GNU.sparse.offset")) {
                                    if (offset != null) {
                                        // previous GNU.sparse.offset header but but no numBytes
                                        sparseHeaders.add(new TarArchiveStructSparse(offset, 0));
                                    }
                                    offset = Long.valueOf(value);
                                }

                                // for 0.0 PAX Headers
                                if (keyword.equals("GNU.sparse.numbytes")) {
                                    if (offset == null) {

View on GitHub (pinned to 0152f468fc)