apache/dubbo · error · IndexOutOfBoundsException

base642bytes: length < 0, length is {}

Error message

base642bytes: length < 0, length is {}

What it means

Thrown by the String-alphabet Base64 decoder Bytes.base642bytes(String, int off, int len, String code) when `len` is negative. Length drives the output byte-array sizing and the decode loop bound, so a negative length is invalid and rejected with IndexOutOfBoundsException up front. Convenience overloads that compute len from str.length() never trigger this.

Source

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

    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.");
        }

        int num = len / 4, size = num * 3;

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Use base642bytes(str) or base642bytes(str, code) to let the API derive len = str.length().
  2. Compute defensively: int len = Math.max(0, end - start);
  3. Surface bad producers with a precondition on the length source.

Example fix

// before
byte[] b = Bytes.base642bytes(str, off, end - start, C64); // negative when end < start
// after
int len = Math.max(0, end - start);
byte[] b = Bytes.base642bytes(str, off, len, C64);
Defensive patterns

Strategy: validation

Validate before calling

if (len < 0) throw new IllegalArgumentException("len must be >= 0, got " + len);
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 length", e);
}

Prevention

When it happens

Trigger: Calling base642bytes(str, off, len, code) with len < 0; computing len = end - start with end < start; passing -1 as a sentinel (none is supported here).

Common situations: Off-by-one in substring slicing; a length field that was never initialized (default -1); porting from an API where -1 meant 'whole string'.

Related errors


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