apache/dubbo · error · IndexOutOfBoundsException
bytes2base64: length < 0, length is {}
Error message
bytes2base64: length < 0, length is {} What it means
Thrown by the canonical Base64 encoder Bytes.bytes2base64(byte[], int off, int len, char[] code) when the supplied region length `len` is negative. The encoder sizes its output char array from `len`, so a negative length is meaningless; the method fails fast with IndexOutOfBoundsException instead of allocating a bogus buffer or producing corrupt output. All convenience overloads (bytes2base64(byte[]), bytes2base64(byte[],int,int), bytes2base64(byte[],String), etc.) eventually forward `len` to this check.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java:531
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;
cs[w++] = code[b1 >> 2];
cs[w++] = code[(b1 << 4) & MASK6 | (b2 >> 4)];View on GitHub (pinned to 3a3043227f)
Solutions
- Compute the length defensively before calling: int len = Math.max(0, end - start);
- Prefer a convenience overload that derives the length for you: bytes2base64(byte[]) or bytes2base64(byte[], int offset, int length) with a validated length.
- Add a precondition at the producer that computes `len` so the bad value is surfaced at its source.
Example fix
// before int len = end - start; // can be negative if end < start String s = Bytes.bytes2base64(bs, off, len, Bytes.BASE64); // after int len = Math.max(0, end - start); String s = Bytes.bytes2base64(bs, off, len, Bytes.BASE64);
Defensive patterns
Strategy: validation
Validate before calling
if (len < 0) throw new IllegalArgumentException("len must be >= 0, got " + len);
String s = Bytes.bytes2base64(bs, off, len, Bytes.BASE64); Try / catch
try {
String s = Bytes.bytes2base64(bs, off, len, Bytes.BASE64);
} catch (IndexOutOfBoundsException e) {
// external/untrusted offset/length — log and reject the input
throw new IllegalArgumentException("invalid encode region", e);
} Prevention
- Never use -1 as a length sentinel for this API.
- Derive length from array bounds (bs.length - off) instead of computing it separately.
- Prefer the bytes2base64(byte[]) convenience overload when encoding the whole array.
When it happens
Trigger: Calling bytes2base64(bs, off, len, code) with len < 0; or a convenience overload where the caller computed len = endIndex - startIndex with endIndex < startIndex; or passing -1 as a 'to-end' sentinel (this API has no sentinel semantics).
Common situations: Off-by-one when slicing a sub-array before encoding; a length field that defaults to -1 and was never set; code ported from an API where -1 meant 'rest of array'; serialized payload whose declared length is negative due to truncation.
Related errors
- bytes2base64: offset + length > array length.
- base642bytes: offset < 0, offset is {}
- base642bytes: length < 0, length is {}
- base642bytes: offset + length > string length.
- unterminated escape sequence at index ${i} of: ${str}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/14ce8c149fe43cec.
Report an issue: GitHub.