apache/dubbo · error · IndexOutOfBoundsException
bytes2hex: offset + length > array length.
Error message
bytes2hex: offset + length > array length.
What it means
Thrown by Bytes.bytes2hex(byte[], int, int) when off + len exceeds the byte array length. This is the upper-bound check ensuring the requested region [off, off+len) stays within the array. It runs after the offset and length sign checks, and prevents ArrayIndexOutOfBoundsException during the conversion loop.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java:405
}
/**
* to hex string.
*
* @param bs byte array.
* @param off offset.
* @param len length.
* @return hex string.
*/
public static String bytes2hex(byte[] bs, int off, int len) {
if (off < 0) {
throw new IndexOutOfBoundsException("bytes2hex: offset < 0, offset is " + off);
}
if (len < 0) {
throw new IndexOutOfBoundsException("bytes2hex: length < 0, length is " + len);
}
if (off + len > bs.length) {
throw new IndexOutOfBoundsException("bytes2hex: offset + length > array length.");
}
byte b;
int r = off, w = 0;
char[] cs = new char[len * 2];
for (int i = 0; i < len; i++) {
b = bs[r++];
cs[w++] = BASE16[b >> 4 & MASK4];
cs[w++] = BASE16[b & MASK4];
}
return new String(cs);
}
/**
* from hex string.
*
* @param str hex string.
* @return byte array.View on GitHub (pinned to 3a3043227f)
Solutions
- Recompute or clamp len against the actual current array length: len = Math.min(len, bs.length - off).
- Use bytes2hex(byte[]) for the full array to avoid manual region math.
- Ensure the array reference and its computed region are derived from the same source state.
Example fix
// before byte[] slice = Arrays.copyOfRange(buf, 0, 10); String hex = Bytes.bytes2hex(slice, 0, buf.length); // throws [153]: buf.length > slice.length // after String hex = Bytes.bytes2hex(slice, 0, slice.length);
Defensive patterns
Strategy: validation
Validate before calling
if (off + len > bs.length) len = bs.length - off; // clamp String hex = Bytes.bytes2hex(bs, off, len);
Prevention
- Recompute len against the actual array length after any buffer resize/truncation.
- Use bytes2hex(byte[]) to avoid region arithmetic entirely.
- Derive the array and its region from the same source state.
When it happens
Trigger: Calling Bytes.bytes2hex(bs, off, len) where off + len > bs.length. Stale array reference whose size shrank after the offset/length were computed; off-by-one where len includes one extra byte; passing array.length as offset with len > 0.
Common situations: Reusing a length computed against a larger buffer on a smaller sliced array; reading a length-prefixed field then truncating the buffer but keeping the old length; buffer reuse/recycling mismatch.
Related errors
- bytes2hex: offset < 0, offset is {}
- bytes2hex: length < 0, length is {}
- hex2bytes: offset < 0, offset is {}
- hex2bytes: length < 0, length is {}
- hex2bytes: offset + length > array length.
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/c0e71d9401c713aa.
Report an issue: GitHub.