Tencent/tinker · error · ZipException

Size mismatch

Error message

Size mismatch

What it means

Companion to the CRC check: for STORED entries the stream tracks crcDataSize, the number of bytes actually written for the current entry, and closeEntry() requires currentEntry.getSize() to equal it. A mismatch means the declared size on the ZipEntry was wrong for the bytes written. Both checks exist because STORED entries carry their metadata up front in the local file header and cannot be patched after the fact without seeking.

Source

Thrown at third-party/tinker-ziputils/src/main/java/com/tencent/tinker/ziputils/ziputil/AlignedZipOutputStream.java:158

     * @throws IOException
     *             If an error occurs closing the entry.
     */
    public void closeEntry() throws IOException {
        checkOpen();
        if (currentEntry == null) {
            return;
        }
        if (currentEntry.getMethod() == DEFLATED) {
            super.finish();
        }

        // Verify values for STORED types
        if (currentEntry.getMethod() == STORED) {
            if (crc.getValue() != currentEntry.getCrc()) {
                throw new ZipException("CRC mismatch");
            }
            if (currentEntry.getSize() != crcDataSize) {
                throw new ZipException("Size mismatch");
            }
        }

        int curOffset = LOCHDR;

        // Write the DataDescriptor
        if (currentEntry.getMethod() != STORED) {
            curOffset += EXTHDR;
            writeLong(out, EXTSIG);
            currentEntry.setCrc(crc.getValue());
            writeLong(out, currentEntry.getCrc());
            currentEntry.setCompressedSize(def.getTotalOut());
            writeLong(out, currentEntry.getCompressedSize());
            currentEntry.setSize(def.getTotalIn());
            writeLong(out, currentEntry.getSize());
        }
        // Update the CentralDirectory
        // http://www.pkware.com/documents/casestudies/APPNOTE.TXT

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Set size (and compressedSize) to the exact length of the byte array/stream you will write, and write exactly that many bytes — buffer content in memory (or temp file) first if needed.
  2. Recompute all STORED metadata (size + CRC) from the final payload right before putNextEntry rather than reusing metadata from another archive.
  3. If the content length is genuinely unknown, switch the entry to DEFLATED so the stream can emit a data descriptor.

Example fix

// before: declared size copied from source, content re-encoded
entry.setSize(srcEntry.getSize());
zos.putNextEntry(entry);
zos.write(newContent); // throws Size mismatch

// after: declare size from the actual payload
byte[] newContent = encode(...);
entry.setSize(newContent.length);
entry.setCompressedSize(newContent.length);
entry.setCrc(crcOf(newContent));
zos.putNextEntry(entry);
zos.write(newContent);
Defensive patterns

Strategy: validation

Validate before calling

// Assert declared size equals the payload length before adding the entry
if (entry.getMethod() == java.util.zip.ZipEntry.STORED && entry.getSize() != data.length) {
    throw new IllegalStateException("declared size " + entry.getSize()
        + " != payload length " + data.length + " for " + entry.getName());
}

Try / catch

try {
    zos.closeEntry();
} catch (java.util.zip.ZipException e) {
    if ("Size mismatch".equals(e.getMessage())) {
        throw new IllegalStateException("STORED entry " + entry.getName() + " size disagrees with bytes written", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: putNextEntry of a STORED entry whose setSize() disagrees with the byte count later passed to write() — e.g. size taken from a source zip entry but content filtered/modified, or an off-by-N in a partial-write loop.

Common situations: Repackaging APKs/zip archives with alignment (this class's purpose) while altering entry contents; copying entries with `entry.setSize(source.getSize())` but writing a different length; padding/alignment adjustments applied to the data but not reflected in size.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/fefe8ad4f8ec38ee. Report an issue: GitHub.