apache/dubbo · error · IndexOutOfBoundsException

base642bytes: offset < 0, offset is {}

Error message

base642bytes: offset < 0, offset is {}

What it means

Thrown by the String-alphabet Base64 decoder Bytes.base642bytes(String, int off, int len, String code) when the offset `off` is negative. The decoder reads str.charAt(off + ...) so a negative offset would produce malformed indexes; it fails fast with IndexOutOfBoundsException. The same guard exists in the char[]-alphabet overload.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/io/Bytes.java:618

     * @param code base64 code(0-63 is base64 char,64 is pad char).
     * @return byte array.
     */
    public static byte[] base642bytes(String str, String code) {
        return base642bytes(str, 0, str.length(), code);
    }

    /**
     * from base64 string.
     *
     * @param str  base64 string.
     * @param off  offset.
     * @param len  length.
     * @param code base64 code(0-63 is base64 char,64 is pad char).
     * @return byte array.
     */
    public static byte[] base642bytes(final String str, final int off, final int len, final String code) {
        if (off < 0) {
            throw new IndexOutOfBoundsException("base642bytes: offset < 0, offset is " + off);
        }
        if (len < 0) {
            throw new IndexOutOfBoundsException("base642bytes: length < 0, length is " + len);
        }
        if (len == 0) {
            return new byte[0];
        }
        if (off + len > str.length()) {
            throw new IndexOutOfBoundsException("base642bytes: offset + length > string length.");
        }

        if (code.length() < 64) {
            throw new IllegalArgumentException("Base64 code length < 64.");
        }

        int rem = len % 4;
        if (rem == 1) {
            throw new IllegalArgumentException("base642bytes: base64 string length % 4 == 1.");

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Check the producer of the offset, especially indexOf/lastIndexOf results: if (idx < 0) handle not-found.
  2. Prefer base642bytes(str) or base642bytes(str, code) which start at offset 0.
  3. Clamp/validate: if (off < 0) throw new IllegalArgumentException(...).

Example fix

// before
int idx = str.indexOf(separator);
byte[] b = Bytes.base642bytes(str, idx, len, C64); // idx == -1 when not found
// after
int idx = str.indexOf(separator);
if (idx < 0) throw new IllegalArgumentException("separator not found");
byte[] b = Bytes.base642bytes(str, idx, len, C64);
Defensive patterns

Strategy: validation

Validate before calling

if (off < 0) throw new IllegalArgumentException("off must be >= 0, got " + off);
byte[] b = Bytes.base642bytes(str, off, len, Bytes.C64);

Try / catch

try {
    byte[] b = Bytes.base642bytes(str, off, len, Bytes.C64);
} catch (IndexOutOfBoundsException e) {
    throw new IllegalArgumentException("invalid decode offset", e);
}

Prevention

When it happens

Trigger: Calling base642bytes(str, off, len, code) with off < 0; an offset derived from a search that returned -1 (not found) and was used unchecked as a position.

Common situations: Using String.indexOf result directly as the offset without checking for -1; an offset field defaulting to -1; arithmetic like off = pos - len where pos < len.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/a986b44dbd363dc3. Report an issue: GitHub.