Tencent/matrix · error · IOException

bad idSize:

Error message

bad idSize: 

What it means

HprofWriter.visitHeader() validates the hprof header's idSize field before writing it. An idSize that is zero, negative, or >= Integer.MAX_VALUE>>1 would corrupt every subsequent ID-bearing record, so the writer rejects it with an IOException. This guards against upstream readers producing garbage header data.

Solutions

  1. Inspect the source hprof header bytes and fix/correct the idSize (typically 4 or 8).
  2. Re-capture the heap dump if the source file header is corrupt.
  3. Ensure the reader feeding the writer was constructed with the correct header parsing (check the first bytes: 'java profile 1.0.1' + idSize int).
  4. If rewriting dumps programmatically, hard-code/validate idSize as 4 or 8 before writing.

Example fix

// before: passing through whatever the reader got
writer.visitHeader(text, readerHeaderIdSize, timestamp);

// after: validate before writing
int idSize = readerHeaderIdSize;
if (idSize != 4 && idSize != 8) {
    throw new IOException("unexpected hprof idSize: " + idSize);
}
writer.visitHeader(text, idSize, timestamp);
Defensive patterns

Strategy: validation

Validate before calling

static void validateIdSize(int idSize) {
    if (idSize != 4 && idSize != 8)
        throw new IllegalArgumentException("hprof idSize must be 4 or 8, got " + idSize);
}

Try / catch

try {
    writer.visitHeader(text, idSize, timestamp);
} catch (IOException e) {
    if (e.getMessage().startsWith("bad idSize")) {
        // fix/normalize idSize before retrying
    }
}

Prevention

When it happens

Trigger: Converting or rewriting an hprof whose header was parsed with a bad idSize; feeding an HprofWriter from a reader whose source file header is corrupt; passing idSize read as 0 from an empty/truncated header.

Common situations: hprof post-processing pipelines (e.g. trimming or re-serializing dumps) that read a truncated header; hprof files generated by non-standard tools writing idSize 0.

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


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/a6cbfc68484fd2c7. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-resource-canary/matrix-resource-canary-android/src/main/java/com/tencent/matrix/resource/hproflib/HprofWriter.java:47

 * Created by tangyinsheng on 2017/6/27.
 */

public class HprofWriter extends HprofVisitor {
    private final OutputStream mStreamOut;
    private int mIdSize = 0;

    private final ByteArrayOutputStream mHeapDumpOut = new ByteArrayOutputStream();

    public HprofWriter(OutputStream os) {
        super(null);
        mStreamOut = os;
    }

    @Override
    public void visitHeader(String text, int idSize, long timestamp) {
        try {
            if (idSize <= 0 || idSize >= (Integer.MAX_VALUE >> 1)) {
                throw new IOException("bad idSize: " + idSize);
            }
            mIdSize = idSize;
            IOUtil.writeNullTerminatedString(mStreamOut, text);
            IOUtil.writeBEInt(mStreamOut, idSize);
            IOUtil.writeBELong(mStreamOut, timestamp);
        } catch (Throwable thr) {
            throw new RuntimeException(thr);
        }
    }

    @Override
    public void visitStringRecord(ID id, String text, int timestamp, long length) {
        try {
            mStreamOut.write(HprofConstants.RECORD_TAG_STRING);
            IOUtil.writeBEInt(mStreamOut, timestamp);
            IOUtil.writeBEInt(mStreamOut, (int) length);
            mStreamOut.write(id.getBytes());
            IOUtil.writeString(mStreamOut, text);

View on GitHub (pinned to 3b8293bd65)