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

  1. 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.
  2. Recreate the TarArchiveEntry immediately before writing (e.g. new TarArchiveEntry(file, name)) so the header size reflects current file content.
  3. If streaming unknown-length data, write it to a temp file or ByteArrayOutputStream first, size the entry from that, then write the bytes.
  4. 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

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


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