MuntashirAkon/AppManager · error · IOException
Wrong header version: " + s
Error message
Wrong header version: " + s
What it means
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.
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
Example fix
// before
InputStream is = new FileInputStream("backup.tar"); // wrong format
new AndroidBackupHeader(is, pwd).toTar();
// after
InputStream is = new FileInputStream("backup.ab");
String head = readFirstLine(is);
if (!"ANDROID BACKUP".equals(head)) throw new IOException("Not an Android backup");
new AndroidBackupHeader(is, pwd).toTar(); Defensive patterns
Strategy: validation
Validate before calling
// Check the version line before handing the stream to the header parser
List<String> lines = readHeaderLines(abFile, 2);
if (!"ANDROID BACKUP".equals(lines.get(0))) throw new IOException("Not an Android backup");
if (!"1".equals(lines.get(1))) throw new IOException("Unsupported backup version: " + lines.get(1)); Try / catch
try {
InputStream tar = header.toTar();
} catch (IOException e) {
if (e.getMessage().startsWith("Wrong header version")) {
Log.e(TAG, "Backup format version not supported; convert first", e);
} else throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Didn't read the right header magic
- ADB restore is requested but there are no .ab files.
- An uninstallation was necessary but couldn't perform it.
- Android System (android) cannot be backed up.
- Android System (android) cannot be restored.
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/68081d2cfc3a61ac.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/adb/AndroidBackupHeader.java:96
String s = readHeaderLine(backupStream);
mBackupFileVersion = Integer.parseInt(s);
if (mBackupFileVersion <= BACKUP_FILE_VERSION) {
// okay, it's a version we recognize. if it's version 1, we may need
// to try two different PBKDF2 regimes to compare checksums.
final boolean pbkdf2Fallback = (mBackupFileVersion == 1);
s = readHeaderLine(backupStream);
mCompress = (Integer.parseInt(s) != 0);
s = readHeaderLine(backupStream);
if (s.equals("none")) {
// no more header to parse; we're good to go
} else if (mPassword != null && mPassword.length > 0) { // AES-256
preCompressStream = decodeAesHeaderAndInitialize(mPassword, s, pbkdf2Fallback, backupStream);
} else {
throw new IOException("Archive is encrypted but no password given");
}
} else {
throw new IOException("Wrong header version: " + s);
}
} else {
throw new IOException("Didn't read the right header magic");
}
// okay, use the right stream layer based on compression
return mCompress ? new InflaterInputStream(preCompressStream) : preCompressStream;
}
@NonNull
public OutputStream write(@NonNull OutputStream backupStream) throws Exception {
// Write the global file header. All strings are UTF-8 encoded; lines end
// with a '\n' byte. Actual backup data begins immediately following the
// final '\n'.
//
// line 1: "ANDROID BACKUP"
// line 2: backup file format version, currently "5"
// line 3: compressed? "0" if not compressed, "1" if compressed.View on GitHub (pinned to 0152f468fc)