{"record":{"id":"54c89fb7b24eabe1","repo":"MuntashirAkon/AppManager","slug":"failed-to-read-paxheader-gnu-sparse-offset-is-expected","errorCode":null,"errorMessage":"Failed to read Paxheader.GNU.sparse.offset is expected before GNU.sparse.numbytes shows up.","messagePattern":"Failed to read Paxheader\\.GNU\\.sparse\\.offset is expected before GNU\\.sparse\\.numbytes shows up\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java","lineNumber":744,"sourceCode":"                                       + \"Value should end with a newline\");\n                                }\n                                final String value = new String(rest, 0,\n                                        restLen - 1, StandardCharsets.UTF_8);\n                                headers.put(keyword, value);\n\n                                // for 0.0 PAX Headers\n                                if (keyword.equals(\"GNU.sparse.offset\")) {\n                                    if (offset != null) {\n                                        // previous GNU.sparse.offset header but but no numBytes\n                                        sparseHeaders.add(new TarArchiveStructSparse(offset, 0));\n                                    }\n                                    offset = Long.valueOf(value);\n                                }\n\n                                // for 0.0 PAX Headers\n                                if (keyword.equals(\"GNU.sparse.numbytes\")) {\n                                    if (offset == null) {\n                                        throw new IOException(\"Failed to read Paxheader.\" +\n                                                \"GNU.sparse.offset is expected before GNU.sparse.numbytes shows up.\");\n                                    }\n                                    sparseHeaders.add(new TarArchiveStructSparse(offset, Long.parseLong(value)));\n                                    offset = null;\n                                }\n                            }\n                            break;\n                        }\n                        coll.write((byte) ch);\n                    }\n                    break; // Processed single header\n                }\n\n                // COMPRESS-530 : throw if we encounter a non-number while reading length\n                if (ch < '0' || ch > '9') {\n                    throw new IOException(\"Failed to read Paxheader. Encountered a non-number while reading length\");\n                }\n","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java#L726-L762","documentation":"Thrown by TarUtils.parsePaxHeaders when a GNU.sparse.numbytes record is encountered without a preceding GNU.sparse.offset record. GNU sparse file format 0.0 encodes extents as offset/numbytes pairs, and order matters; a numbytes without an offset indicates malformed PAX data.","triggerScenarios":"Reading a TAR with GNU sparse 0.0 PAX headers where the numbytes keyword appears before any offset keyword, or after the pair was already consumed and offset reset to null.","commonSituations":"Archives created by buggy sparse-file writers, or PAX headers edited/reordered by other tools that dropped the offset record.","solutions":["Re-pack the sparse archive with GNU tar (tar -S --format=pax) so offset/numbytes pairs are emitted in order","Ensure your writer always emits GNU.sparse.offset immediately before each GNU.sparse.numbytes","If sparse support isn't needed, extract the archive with a tool that expands sparse files first","Catch IOException and treat the archive as malformed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    // read tar\n} catch (IOException e) {\n    if (e.getMessage().contains(\"GNU.sparse.offset is expected\")) {\n        throw new CorruptArchiveException(\"GNU sparse PAX records out of order\", e);\n    }\n    throw e;\n}","preventionTips":["Emit GNU.sparse.offset immediately before each GNU.sparse.numbytes when writing sparse archives","Use GNU tar to create sparse archives rather than custom writers","Expand sparse files before re-archiving with other tools"],"tags":["tar","pax-header","gnu-sparse","malformed-data"],"backgroundTag":"invalid-state-transition","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}