MuntashirAkon/AppManager · error · IOException
Entry ' ' closed at ' ' before the ' ' bytes specified in…
Error message
Entry '${currName}' closed at '${currBytes}' before the '${currSize}' bytes specified in the header were written What it means
closeArchiveEntry verifies that the number of bytes written for the current entry equals the size declared in the tar header (setSize). If fewer bytes were written (currBytes < currSize), the archive would contain an entry whose data does not match its header, so the library throws with details of the shortfall.
Solutions
- Set entry size from the actual data: entry.setSize(data.length) or file.length(), and write exactly that many bytes.
- Copy the whole source stream and verify byte counts before closing.
- If the source may be truncated, read it fully into memory or adjust the size before putArchiveEntry (size is fixed once the header is written).
Example fix
// before entry.setSize(1024); // guessed tar.putArchiveEntry(entry); tar.write(data); // data.length == 900 // after entry.setSize(data.length); tar.putArchiveEntry(entry); tar.write(data); tar.closeArchiveEntry();
Defensive patterns
Strategy: validation
Validate before calling
long actual = data.length; // or Files.size(path) if (actual != entry.getSize()) entry.setSize(actual);
Try / catch
try {
tar.closeArchiveEntry();
} catch (IOException e) {
if (e.getMessage().contains("before the '")) {
// entry under-written: mark archive invalid, rewrite with correct size
} else throw e;
} Prevention
- Always setSize from the real data length
- Count bytes copied and compare to entry size
- Avoid hard-coded sizes
- Read sources fully (or verify availability) before writing the header
When it happens
Trigger: Closing an entry after writing fewer bytes than TarArchiveEntry.getSize(); passing a smaller InputStream to copy than the declared size; setting an inflated size manually before writing.
Common situations: Hard-coded entry sizes out of sync with actual file content; interrupted file reads; computing size with one encoding/unit and writing with another; copying from a truncated source stream.
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
- APK files backup is requested but no APK files have been…
- APK files backup is requested but no APK files have been…
- APK files backup is requested but no APK files have been…
- APK files backup is requested but no source directory has…
- At offset , byte binary number exceeds maximum signed long…
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/5f77fbc87b659173.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveOutputStream.java:414
/**
* Close an entry. This method MUST be called for all file entries that contain data. The reason
* is that we must buffer data written to the stream in order to satisfy the buffer's record
* based writes. Thus, there may be data fragments still being assembled that must be written to
* the output stream before this entry is closed and the next entry written.
*
* @throws IOException on error
*/
@Override
public void closeArchiveEntry() throws IOException {
if (finished) {
throw new IOException("Stream has already been finished");
}
if (!haveUnclosedEntry) {
throw new IOException("No current entry to close");
}
out.flushBlock();
if (currBytes < currSize) {
throw new IOException("Entry '" + currName + "' closed at '"
+ currBytes
+ "' before the '" + currSize
+ "' bytes specified in the header were written");
}
recordsWritten += (int) (currSize / RECORD_SIZE);
if (0 != currSize % RECORD_SIZE) {
recordsWritten++;
}
haveUnclosedEntry = false;
}
/**
* 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.View on GitHub (pinned to 0152f468fc)