{"record":{"id":"d769e1d5a5ae080b","repo":"apache/pulsar","slug":"invalid-messageidv5-data-too-short","errorCode":null,"errorMessage":"Invalid MessageIdV5 data: too short","messagePattern":"Invalid MessageIdV5 data: too short","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/MessageIdV5.java","lineNumber":267,"sourceCode":"                    buf.putInt(seg.getValue().length);\n                    buf.put(seg.getValue());\n                }\n            }\n        }\n        return buf.array();\n    }\n\n    private static Map<Long, byte[]> serializeSegmentVector(Map<Long, MessageId> vector) {\n        Map<Long, byte[]> out = new HashMap<>(vector.size());\n        for (var entry : vector.entrySet()) {\n            out.put(entry.getKey(), entry.getValue().toByteArray());\n        }\n        return out;\n    }\n\n    static MessageIdV5 fromByteArray(byte[] data) throws IOException {\n        if (data == null || data.length < 12) {\n            throw new IOException(\"Invalid MessageIdV5 data: too short\");\n        }\n        ByteBuffer buf = ByteBuffer.wrap(data);\n        long segmentId = buf.getLong();\n        int v4Length = buf.getInt();\n        if (v4Length < 0 || v4Length > buf.remaining()) {\n            throw new IOException(\"Invalid MessageIdV5 data: bad v4 length\");\n        }\n        byte[] v4Bytes = new byte[v4Length];\n        buf.get(v4Bytes);\n        MessageId v4Id = MessageId.fromByteArray(v4Bytes);\n\n        // Section 3: position vector (single-topic / per-segment).\n        Map<Long, MessageId> positions = Map.of();\n        if (buf.hasRemaining()) {\n            positions = readSegmentVector(buf);\n        }\n\n        // Section 4: parent topic. Length -1 sentinel means \"absent\".","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/MessageIdV5.java#L249-L285","documentation":"MessageIdV5.fromByteArray requires at least 12 bytes: 8 bytes for the segmentId (long) plus 4 bytes for the v4-length (int). Shorter arrays cannot contain the fixed header, so it throws IOException('Invalid MessageIdV5 data: too short'). It protects against null/truncated/corrupt message id blobs.","triggerScenarios":"Calling MessageIdV5.fromByteArray(null), an empty array, or any array shorter than 12 bytes — typically a truncated id read from a topic, bookkeeper ledger, or custom store.","commonSituations":"Storing message ids in a fixed-size column too small for the v5 format; cutting/pasting id bytes between formats (e.g. treating a 10-byte legacy id as v5); corruption during serialization to disk.","solutions":["Check data != null && data.length >= 12 before calling fromByteArray.","Confirm the bytes were produced by MessageIdV5.toByteArray (v4 ids use a different, shorter format — use the matching deserializer).","Re-fetch the message id from the source instead of deserializing the damaged copy."],"exampleFix":"// before\nMessageIdV5 id = MessageIdV5.fromByteArray(stored);\n// after\nif (stored == null || stored.length < 12) {\n    throw new IOException(\"Stored id missing/truncated, re-resolve from source\");\n}\nMessageIdV5 id = MessageIdV5.fromByteArray(stored);","handlingStrategy":"validation","validationCode":"if (data == null || data.length < 12) {\n    throw new IOException(\"Stored message id missing or truncated (\"\n            + (data == null ? 0 : data.length) + \" bytes)\");\n}","typeGuard":"static boolean isPlausibleMessageIdV5(byte[] data) {\n    return data != null && data.length >= 12;\n}","tryCatchPattern":"try {\n    MessageIdV5 id = MessageIdV5.fromByteArray(data);\n} catch (IOException e) {\n    log.warn(\"Corrupt message id blob, re-resolving from source\", e);\n}","preventionTips":["Store the byte length alongside the blob and validate on read.","Use MessageIdV5.toByteArray for serialization — never mix with v4 encodings.","Write id blobs atomically to avoid truncation on crash."],"tags":["deserialization","message-id","corrupt-data"],"backgroundTag":"invalid-message-id-data","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}