pinpoint-apm/pinpoint · error · IllegalArgumentException
invalid varLong. start offset:${offset} readOffset:${offset}
Error message
invalid varLong. start offset:${offset} readOffset:${offset} What it means
FixedBuffer.readVar64SlowPath decodes LEB128-style variable-length 64-bit integers. If it reads the maximum number of continuation bytes without hitting a terminating byte (high bit clear), the buffer content is not a valid varLong and it throws IllegalArgumentException 'invalid varLong. start offset:... readOffset:...'.
Source
Thrown at commons-buffer/src/main/java/com/navercorp/pinpoint/common/buffer/FixedBuffer.java:401
}
return (int) readVar64SlowPath();
}
/** Variant of readRawVarint64 for when uncomfortably close to the limit. */
/* Visible for testing */
long readVar64SlowPath() {
int copyOffset = this.offset;
long result = 0;
for (int shift = 0; shift < 64; shift += 7) {
final byte b = this.buffer[copyOffset++];
result |= (long) (b & 0x7F) << shift;
if ((b & 0x80) == 0) {
this.offset = copyOffset;
return result;
}
}
throw new IllegalArgumentException("invalid varLong. start offset:" + this.offset + " readOffset:" + offset);
}
@Override
public int readSVInt() {
return BytesUtils.zigzagToInt(readVInt());
}
@Override
public short readShort() {
final short i = ByteArrayUtils.bytesToShort(buffer, offset);
this.offset = this.offset + ByteArrayUtils.SHORT_BYTE_LENGTH;
return i;
}
public int readUnsignedShort() {
return readShort() & 0xFFFF;
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Verify the byte range being decoded actually starts at a varint boundary; fix the caller's offset.
- Check data was written by a compatible Pinpoint version (codec/schema mismatch).
- Validate or re-write the corrupted row/cell in storage.
- Catch IllegalArgumentException around readVInt/readVLong when decoding untrusted data and log the raw bytes.
Example fix
// before
long v = buffer.readVLong();
// after
try {
long v = buffer.readVLong();
} catch (IllegalArgumentException e) {
logger.warn("bad varint at offset, buffer={} ", BytesUtils.toString(buffer.getBuffer()), e);
throw new CorruptBufferException(e);
} Defensive patterns
Strategy: validation
Validate before calling
public static boolean isLikelyVarInt(byte[] buf, int offset) {
for (int i = 0; i < 10 && offset + i < buf.length; i++) {
if ((buf[offset + i] & 0x80) == 0) return true; // terminator found
}
return false;
} Try / catch
try {
long value = buffer.readVLong();
} catch (IllegalArgumentException e) {
logger.warn("malformed varint: {}", e.getMessage());
throw new CorruptBufferException("bad varint in cell " + rowKey, e);
} Prevention
- Always read varints at offsets produced by the matching writer's encode path.
- Version-stamp serialized payloads and check before decoding.
- Fuzz-test decoders against truncated inputs.
When it happens
Trigger: readVInt() or readVLong() invoked on bytes where the varint never terminates within the allowed shifts — either the byte stream is corrupt, the read offset is misaligned, or a fixed-width value is being read as a varint.
Common situations: Deserializing a corrupted/truncated HBase cell value; reading a buffer written by a different codec version (schema mismatch); offset arithmetic errors by the caller before calling readVInt/readVLong; treating non-varint-encoded legacy data as varint.
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
- unsupported DataType:${dataType}
- Unknown attribute type code: ${typeCode}
- unsupported type:${dataType}
- unsupported DataType:${typeCode} data:${o}
- unknown MethodType:${code}
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/98582a24611a224c.
Report an issue: GitHub.