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.

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.

Appendix: 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)