apache/dubbo · error · IndexOutOfBoundsException
bytes2hex: offset < 0, offset is {}
Error message
bytes2hex: offset < 0, offset is {} What it means
Thrown by Bytes.bytes2hex(byte[], int, int) when the offset argument is negative. The method converts a region of a byte array to a hexadecimal string; offset must be within [0, array.length]. A negative offset is rejected before any array access as a defensive bounds check to prevent misleading ArrayIndexOutOfBoundsException later.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java:399
*
* @param bs byte array.
* @return hex string.
*/
public static String bytes2hex(byte[] bs) {
return bytes2hex(bs, 0, bs.length);
}
/**
* 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);
}View on GitHub (pinned to 3a3043227f)
Solutions
- Validate offset >= 0 before calling bytes2hex, and clamp or reject invalid input upstream.
- If you always want the whole array, use the single-arg overload bytes2hex(byte[]) which sets offset=0, length=array.length.
- Check the source of the offset value for sign/underflow bugs.
Example fix
// before
int off = cursor - step; // may be negative
String hex = Bytes.bytes2hex(data, off, len); // throws [151]
// after
if (off < 0 || off + len > data.length) throw new IllegalArgumentException("bad range");
String hex = Bytes.bytes2hex(data, off, len); Defensive patterns
Strategy: validation
Validate before calling
if (off < 0 || len < 0 || off + len > bs.length) {
throw new IllegalArgumentException("invalid range off=" + off + " len=" + len + " arr=" + bs.length);
}
String hex = Bytes.bytes2hex(bs, off, len); Prevention
- Prefer the single-arg Bytes.bytes2hex(byte[]) overload when encoding the whole array.
- Range-check offset/length at the boundary where they are computed or parsed.
- Treat -1 sentinels explicitly rather than passing them as offsets.
When it happens
Trigger: Calling Bytes.bytes2hex(bs, off, len) with off < 0. Typically off comes from an arithmetic computation, a parsed integer, or a relative index that underflowed or was not range-checked.
Common situations: Passing a parsed/decoded offset from a binary protocol parser that produced -1 (sentinel) without checking; off-by-one or sign error in index math; passing a cursor variable that was decremented past zero.
Related errors
- bytes2hex: length < 0, length is {}
- bytes2hex: offset + length > array length.
- 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/31ec19d36c3c6315.
Report an issue: GitHub.