apache/dubbo · error · IndexOutOfBoundsException
bytes2base64: offset < 0, offset is {}
Error message
bytes2base64: offset < 0, offset is {} What it means
Thrown by Bytes.bytes2base64(byte[], int, int, char[] code) when the offset argument is negative. This is the first bounds check in the char[]-alphabet overload of base64 encoding; offset must be within [0, bs.length]. It prevents reading before the array start.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java:528
* @param code base64 code(0-63 is base64 char,64 is pad char).
* @return base64 string.
*/
public static String bytes2base64(byte[] b, char[] code) {
return bytes2base64(b, 0, b.length, code);
}
/**
* to base64 string.
*
* @param bs byte array.
* @param off offset.
* @param len length.
* @param code base64 code(0-63 is base64 char,64 is pad char).
* @return base64 string.
*/
public static String bytes2base64(final byte[] bs, final int off, final int len, final char[] code) {
if (off < 0) {
throw new IndexOutOfBoundsException("bytes2base64: offset < 0, offset is " + off);
}
if (len < 0) {
throw new IndexOutOfBoundsException("bytes2base64: length < 0, length is " + len);
}
if (off + len > bs.length) {
throw new IndexOutOfBoundsException("bytes2base64: offset + length > array length.");
}
if (code.length < 64) {
throw new IllegalArgumentException("Base64 code length < 64.");
}
boolean pad = code.length > 64; // has pad char.
int num = len / 3, rem = len % 3, r = off, w = 0;
char[] cs = new char[num * 4 + (rem == 0 ? 0 : pad ? 4 : rem + 1)];
for (int i = 0; i < num; i++) {
int b1 = bs[r++] & MASK8, b2 = bs[r++] & MASK8, b3 = bs[r++] & MASK8;View on GitHub (pinned to 3a3043227f)
Solutions
- Validate offset >= 0 before calling bytes2base64.
- Use bytes2base64(byte[]) for the whole array to avoid manual offset.
- Range-check the offset source at the parsing/computation boundary.
Example fix
// before int off = cursor - 4; // may be negative String b64 = Bytes.bytes2base64(data, off, len, Bytes.BASE64.toCharArray()); // throws [159] // after if (off < 0 || off + len > data.length) throw new IllegalArgumentException(); String b64 = Bytes.bytes2base64(data, off, len, Bytes.BASE64.toCharArray());
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 b64 = Bytes.bytes2base64(bs, off, len, code); Prevention
- Use bytes2base64(byte[]) for full-array encoding.
- Range-check offset/length at the boundary where they are computed.
- Handle -1 sentinels explicitly rather than passing as offsets.
When it happens
Trigger: Calling Bytes.bytes2base64(bs, off, len, code) with off < 0. Typically off is a computed/parsed index that was not validated for non-negativity.
Common situations: Negative offset from underflow in index arithmetic; a parsed offset field that yielded -1; a cursor decremented below zero; reusing an offset computed for a different buffer.
Related errors
- bytes2hex: offset < 0, offset is {}
- bytes2hex: length < 0, length is {}
- bytes2hex: offset + length > array length.
- hex2bytes: offset < 0, offset is {}
- hex2bytes: length < 0, length is {}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/738e18a175b9b5e1.
Report an issue: GitHub.