MuntashirAkon/AppManager · error · IOException
Request to write '${numToWrite}' bytes exceeds size in heade
Error message
Request to write '${numToWrite}' bytes exceeds size in header of '${currSize}' bytes for entry '${currName}' What it means
TarArchiveOutputStream.write() tracks how many bytes have been written for the current entry (currBytes) against the entry's declared size in its tar header (currSize). If a single write call would push the total beyond currSize, the stream refuses to write, since a tar entry's content length is fixed in its header and cannot grow. This protects the archive from corruption: subsequent entries would otherwise be misaligned with block boundaries.
Source
Thrown at app/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java:442
}
/**
* Writes bytes to the current tar archive entry. This method is aware of the current entry and
* will throw an exception if you attempt to write bytes past the length specified for the
* current entry.
*
* @param wBuf The buffer to write to the archive.
* @param wOffset The offset in the buffer from which to get bytes.
* @param numToWrite The number of bytes to write.
* @throws IOException on error
*/
@Override
public void write(final byte[] wBuf, final int wOffset, final int numToWrite) throws IOException {
if (!haveUnclosedEntry) {
throw new IllegalStateException("No current tar entry");
}
if (currBytes + numToWrite > currSize) {
throw new IOException("Request to write '" + numToWrite
+ "' bytes exceeds size in header of '"
+ currSize + "' bytes for entry '"
+ currName + "'");
}
out.write(wBuf, wOffset, numToWrite);
currBytes += numToWrite;
}
/**
* Writes a PAX extended header with the given map as contents.
*
* @since 1.4
*/
void writePaxHeaders(final TarArchiveEntry entry,
final String entryName,
final Map<String, String> headers) throws IOException {
String name = "./PaxHeaders.X/" + stripTo7Bits(entryName);
if (name.length() >= TarConstants.NAMELEN) {View on GitHub (pinned to 0152f468fc)
Solutions
- Ensure the total bytes written match the size returned by TarArchiveEntry.getSize(): buffer the content and create the entry from the exact same data you write.
- Recreate the TarArchiveEntry immediately before writing (e.g. new TarArchiveEntry(file, name)) so the header size reflects current file content.
- If streaming unknown-length data, write it to a temp file or ByteArrayOutputStream first, size the entry from that, then write the bytes.
- Check for double-writes of the same data (e.g. calling write() twice with overlapping buffers).
Example fix
// before TarArchiveEntry entry = new TarArchiveEntry(file, file.getName()); tarOut.putArchiveEntry(entry); tarOut.write(getUpdatedContent()); // length may differ from file size // after byte[] content = getUpdatedContent(); TarArchiveEntry entry = new TarArchiveEntry(file, file.getName()); entry.setSize(content.length); // header size matches actual write tarOut.putArchiveEntry(entry); tarOut.write(content);
Defensive patterns
Strategy: validation
Validate before calling
byte[] content = readAllBytes(file);
if (content.length != entry.getSize()) {
entry.setSize(content.length); // realign header before writing
}
tarOut.putArchiveEntry(entry);
tarOut.write(content);
tarOut.closeArchiveEntry(); Try / catch
try {
tarOut.putArchiveEntry(entry);
tarOut.write(data);
tarOut.closeArchiveEntry();
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("exceeds size in header")) {
// rebuild entry with correct size and retry
} else {
throw e;
}
} Prevention
- Create the TarArchiveEntry from the exact data you will write, right before writing it.
- Track written byte count against entry.getSize() in your archiving loop.
- Never reuse entry objects across different content.
When it happens
Trigger: Calling write(byte[], int, int) with more bytes than remain for the current entry — i.e. currBytes + numToWrite > currSize — while an entry opened via putArchiveEntry is still unclosed. Happens when the caller writes data that differs in length from the size the TarArchiveEntry was created with.
Common situations: Writing a byte array that was mutated or re-read after creating the TarArchiveEntry from a File (file changed size between entry creation and write); reusing an entry object with different content; writing a String's bytes whose length differs from an earlier computed size; wrapping streams that report size at creation but are later updated.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- Record to write has length '${record.length}' which is not t
- Failed to backup data directory at
- Could not backup KeyStore item.
- APK files backup is requested but no APK files have been bac
- Backup failed for
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/8957d1a8abb9d768.
Report an issue: GitHub.