apache/pulsar · error · java.io.IOException
Invalid MessageIdV5 data: bad inner id length
Error message
Invalid MessageIdV5 data: bad inner id length
What it means
readSegmentVector parses section 3: a count, then per entry an 8-byte segment id, a 4-byte inner-id length, and the id bytes. If an inner id length is negative or exceeds remaining bytes, the buffer is corrupt/misaligned, so it throws IOException('Invalid MessageIdV5 data: bad inner id length'). Called from fromByteArray and inner.
Source
Thrown at pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/MessageIdV5.java:326
buf.get(topicBytes);
String topic = new String(topicBytes, StandardCharsets.UTF_8);
Map<Long, MessageId> inner = readSegmentVector(buf);
multiTopic.put(topic, inner);
}
}
}
return new MessageIdV5(v4Id, segmentId, positions, parentTopic, multiTopic);
}
private static Map<Long, MessageId> readSegmentVector(ByteBuffer buf) throws IOException {
int count = buf.getInt();
Map<Long, MessageId> out = new HashMap<>(count);
for (int i = 0; i < count; i++) {
long segId = buf.getLong();
int idLen = buf.getInt();
if (idLen < 0 || idLen > buf.remaining()) {
throw new IOException("Invalid MessageIdV5 data: bad inner id length");
}
byte[] idBytes = new byte[idLen];
buf.get(idBytes);
out.put(segId, MessageId.fromByteArray(idBytes));
}
return out;
}
@Override
public int compareTo(org.apache.pulsar.client.api.v5.MessageId other) {
if (!(other instanceof MessageIdV5 o)) {
throw new IllegalArgumentException("Cannot compare with " + other.getClass());
}
int cmp = Long.compare(this.segmentId, o.segmentId);
if (cmp != 0) {
return cmp;
}
return this.v4MessageId.compareTo(o.v4MessageId);View on GitHub (pinned to 820761864e)
Solutions
- Ensure both writer and reader use the same byte order and framing (ByteBuffer big-endian default).
- Verify the position-vector count matches the number of segment entries actually persisted.
- Regenerate the blob via toByteArray/from the live checkpoint instead of repairing bytes manually.
- Add a length/version header when persisting ids so truncation is detected earlier.
Example fix
// before
byte[] blob = store.load(key); // possibly partial write
MessageIdV5 id = MessageIdV5.fromByteArray(blob);
// after
byte[] blob = store.load(key);
if (blob.length != expectedLen) { // persisted length header
throw new IOException("Partial blob, discarding checkpoint");
}
MessageIdV5 id = MessageIdV5.fromByteArray(blob); Defensive patterns
Strategy: validation
Validate before calling
ByteBuffer buf = ByteBuffer.wrap(data);
buf.getLong(); // segmentId
int v4Len = buf.getInt();
buf.position(buf.position() + v4Len);
if (buf.remaining() < 4) {
throw new IOException("No room for segment-vector count — blob truncated");
}
int count = buf.getInt();
if (8L + 4L * count > buf.remaining()) {
throw new IOException("Segment vector entries exceed remaining bytes");
} Try / catch
try {
MessageIdV5 id = MessageIdV5.fromByteArray(data);
} catch (IOException e) {
log.warn("Corrupt segment vector, rebuilding positions from broker", e);
} Prevention
- Match byte order between writer and reader (ByteBuffer defaults to big-endian).
- Validate per-entry lengths against remaining bytes in any custom parser.
- Avoid hand-rolled serialization of MessageIdV5; use toByteArray/fromByteArray exclusively.
When it happens
Trigger: Deserializing a truncated or offset-shifted blob so the declared id length runs past the buffer end; byte-order mismatch turning the length into a negative/huge value; a count field mismatched with the actual number of entries written.
Common situations: Custom persistence of MessageIdV5 with framing bugs; partial writes from a crashed producer; hand-editing or re-framing checkpoint blobs; mixing little-endian writers with the big-endian ByteBuffer reader.
Related errors
- Invalid MessageIdV5 data: bad v4 length
- Invalid MessageIdV5 data: too short
- Invalid MessageIdV5 data: bad parent-topic length
- Cannot handle message with null messageId
- payload (${payloadSize} bytes) cannot be decoded with schema
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/2f2b1e04c783bd47.
Report an issue: GitHub.