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
- Inspect the source hprof header bytes and fix/correct the idSize (typically 4 or 8).
- Re-capture the heap dump if the source file header is corrupt.
- Ensure the reader feeding the writer was constructed with the correct header parsing (check the first bytes: 'java profile 1.0.1' + idSize int).
- 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
- Always propagate idSize from a correctly parsed hprof header
- Assert idSize is 4 or 8 in pipeline code before writing
- Never hand-construct headers from guessed values
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
- visit bmp instance failed, lost type def of typeId:
- visit string instance failed, lost type def of typeId:
- visit instance failed, lost type def of typeId:
- failure to skip type, cannot find type def of typeid:
- OBJECT type is not a primitive type
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)