Tencent/matrix · error · IOException
bad idSize:
Error message
bad idSize:
What it means
HprofReader.acceptHeader() reads the idSize field from the hprof header. Every object id in the dump is sized by this value, so the reader validates it is a sane positive int (< Integer.MAX_VALUE >> 1) before proceeding; otherwise it throws IOException("bad idSize: ..."), because continuing would corrupt all subsequent ID reads.
Solutions
- Verify the file starts with the hprof magic header 'JAVA PROFILE 1.0.1' / 'JAVA PROFILE 1.0.2' before parsing.
- Re-transfer/re-capture the hprof; check file size and that the copy completed.
- Decompress .hprof.gz files before handing them to HprofReader.
- Wrap accept() in try-catch for IOException and surface a user-friendly 'invalid hprof file' error.
Example fix
// before
new HprofReader(new BufferedInputStream(new FileInputStream(file))).accept(visitor);
// after
try (FileInputStream fis = new FileInputStream(file)) {
byte[] magic = new byte[17];
if (fis.read(magic) < 17 || !new String(magic, 0, 11).equals("JAVA PROFILE")) {
throw new IOException("not a valid hprof file: " + file);
}
new HprofReader(new BufferedInputStream(fis)).accept(visitor);
} Defensive patterns
Strategy: validation
Validate before calling
try (FileInputStream fis = new FileInputStream(file)) {
byte[] head = new byte[18];
if (fis.read(head) < 18 || !new String(head, 0, 11, "US-ASCII").equals("JAVA PROFILE")) {
throw new IOException("not a valid hprof: " + file);
}
} Try / catch
try {
hprofReader.accept(visitor);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("bad idSize")) {
Log.e(TAG, "invalid or corrupt hprof file", e);
}
} Prevention
- Check the 'JAVA PROFILE' magic string before parsing any hprof.
- Decompress gzipped dumps before handing them to HprofReader.
- Verify downloads complete (size/checksum) before parsing.
When it happens
Trigger: Opening a stream with HprofReader.accept() where the bytes at the idSize position of the hprof header decode to <= 0 or >= Integer.MAX_VALUE/2 — i.e. the input is not a valid hprof or the header is misaligned.
Common situations: Passing a non-hprof file (log, HTML error page, empty file) to the parser; truncated download where the header read consumes wrong bytes; wrong file path opened; gzipped hprof not decompressed first.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- zipEntry is null when get from oldApk
- Magic number is wrong -- are you sure this is a DEX file?
- Unable to obtained scaled bitmap's dimensions
- Could not find char array in
- Field does not exists
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/cb7f4bcd76e2d608.
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/HprofReader.java:50
public class HprofReader {
private final InputStream mStreamIn;
private int mIdSize = 0;
public HprofReader(InputStream in) {
mStreamIn = in;
}
public void accept(HprofVisitor hv) throws IOException {
acceptHeader(hv);
acceptRecord(hv);
hv.visitEnd();
}
private void acceptHeader(HprofVisitor hv) throws IOException {
final String text = IOUtil.readNullTerminatedString(mStreamIn);
final int idSize = IOUtil.readBEInt(mStreamIn);
if (idSize <= 0 || idSize >= (Integer.MAX_VALUE >> 1)) {
throw new IOException("bad idSize: " + idSize);
}
final long timestamp = IOUtil.readBELong(mStreamIn);
mIdSize = idSize;
hv.visitHeader(text, idSize, timestamp);
}
private void acceptRecord(HprofVisitor hv) throws IOException {
try {
while (true) {
final int tag = mStreamIn.read();
final int timestamp = IOUtil.readBEInt(mStreamIn);
final long length = IOUtil.readBEInt(mStreamIn) & 0x00000000FFFFFFFFL;
switch (tag) {
case HprofConstants.RECORD_TAG_STRING:
acceptStringRecord(timestamp, length, hv);
break;
case HprofConstants.RECORD_TAG_LOAD_CLASS:
acceptLoadClassRecord(timestamp, length, hv);View on GitHub (pinned to 3b8293bd65)