{"record":{"id":"68081d2cfc3a61ac","repo":"MuntashirAkon/AppManager","slug":"wrong-header-version-s","errorCode":null,"errorMessage":"Wrong header version: \" + s","messagePattern":"Wrong header version: \" \\+ s","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/backup/adb/AndroidBackupHeader.java","lineNumber":96,"sourceCode":"            String s = readHeaderLine(backupStream);\n            mBackupFileVersion = Integer.parseInt(s);\n            if (mBackupFileVersion <= BACKUP_FILE_VERSION) {\n                // okay, it's a version we recognize.  if it's version 1, we may need\n                // to try two different PBKDF2 regimes to compare checksums.\n                final boolean pbkdf2Fallback = (mBackupFileVersion == 1);\n\n                s = readHeaderLine(backupStream);\n                mCompress = (Integer.parseInt(s) != 0);\n                s = readHeaderLine(backupStream);\n                if (s.equals(\"none\")) {\n                    // no more header to parse; we're good to go\n                } else if (mPassword != null && mPassword.length > 0) { // AES-256\n                    preCompressStream = decodeAesHeaderAndInitialize(mPassword, s, pbkdf2Fallback, backupStream);\n                } else {\n                    throw new IOException(\"Archive is encrypted but no password given\");\n                }\n            } else {\n                throw new IOException(\"Wrong header version: \" + s);\n            }\n        } else {\n            throw new IOException(\"Didn't read the right header magic\");\n        }\n\n        // okay, use the right stream layer based on compression\n        return mCompress ? new InflaterInputStream(preCompressStream) : preCompressStream;\n    }\n\n    @NonNull\n    public OutputStream write(@NonNull OutputStream backupStream) throws Exception {\n        // Write the global file header.  All strings are UTF-8 encoded; lines end\n        // with a '\\n' byte.  Actual backup data begins immediately following the\n        // final '\\n'.\n        //\n        // line 1: \"ANDROID BACKUP\"\n        // line 2: backup file format version, currently \"5\"\n        // line 3: compressed?  \"0\" if not compressed, \"1\" if compressed.","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/backup/adb/AndroidBackupHeader.java#L78-L114","documentation":"IOException from AndroidBackupHeader.read when the header version line parsed from the .ab stream is not the supported value (1). The Android backup format version is checked immediately after the magic; any other version is rejected.","triggerScenarios":"The second header line (after 'ANDROID BACKUP') is not \"1\" — e.g. archives from newer tooling with version 2/5, corrupted first lines, or the stream is not actually an Android backup at all.","commonSituations":"Feeding a plain TAR or a compressed file to the extractor; backups produced by alternative implementations using a different version; truncated/mangled transfers shifting header lines.","solutions":["Verify the file starts with 'ANDROID BACKUP\\n1\\n' and is a genuine .ab backup","Use a converter for newer backup versions before this extractor","Re-transfer/re-create the backup if the header is corrupted","Ensure you're not passing a TAR file directly where an .ab is expected"],"exampleFix":"// before\nInputStream is = new FileInputStream(\"backup.tar\"); // wrong format\nnew AndroidBackupHeader(is, pwd).toTar();\n// after\nInputStream is = new FileInputStream(\"backup.ab\");\nString head = readFirstLine(is);\nif (!\"ANDROID BACKUP\".equals(head)) throw new IOException(\"Not an Android backup\");\nnew AndroidBackupHeader(is, pwd).toTar();","handlingStrategy":"validation","validationCode":"// Check the version line before handing the stream to the header parser\nList<String> lines = readHeaderLines(abFile, 2);\nif (!\"ANDROID BACKUP\".equals(lines.get(0))) throw new IOException(\"Not an Android backup\");\nif (!\"1\".equals(lines.get(1))) throw new IOException(\"Unsupported backup version: \" + lines.get(1));","typeGuard":null,"tryCatchPattern":"try {\n    InputStream tar = header.toTar();\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Wrong header version\")) {\n        Log.e(TAG, \"Backup format version not supported; convert first\", e);\n    } else throw e;\n}","preventionTips":["Validate the first two header lines before parsing","Convert non-v1 backups with an external tool first","Verify file integrity after transfer to avoid header corruption","Never feed plain TAR/zip files to the .ab parser"],"tags":["backup","header","version"],"backgroundTag":"invalid-argument-value","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"}