apache/dubbo · error · IllegalArgumentException

base642bytes: base64 string length error.

Error message

base642bytes: base64 string length error.

What it means

Thrown by the String-alphabet Base64 decoder only when the alphabet includes a pad character (code.length() > 64) AND the segment length `len` is not a multiple of 4. Padded Base64 (RFC 4648 style with '=') must always be a multiple of 4 characters; a non-multiple length with a pad-capable alphabet is malformed and is rejected with IllegalArgumentException. (Without a pad char, trailing groups of 2 or 3 chars are allowed.)

Source

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

            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;
        if (code.length() > 64) {
            if (rem != 0) {
                throw new IllegalArgumentException("base642bytes: base64 string length error.");
            }

            char pc = code.charAt(64);
            if (str.charAt(off + len - 2) == pc) {
                size -= 2;
                --num;
                rem = 2;
            } else if (str.charAt(off + len - 1) == pc) {
                size--;
                --num;
                rem = 3;
            }
        } else {
            if (rem == 2) {
                size++;
            } else if (rem == 3) {
                size += 2;
            }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Restore standard padding: append '=' until length is a multiple of 4 before decoding.
  2. If you control the alphabet, decode with a no-pad alphabet (exactly 64 chars) which tolerates trailing groups of 2 or 3.
  3. Sanitize untrusted Base64: s = s.replaceAll("[^A-Za-z0-9+/]", ""); then re-pad to a multiple of 4.

Example fix

// before
byte[] b = Bytes.base642bytes("ZHViYm8", 0, 7, Bytes.C64); // 7 not multiple of 4
// after
String s = "ZHViYm8";
while (s.length() % 4 != 0) s += "=";
byte[] b = Bytes.base642bytes(s, 0, s.length(), Bytes.C64);
Defensive patterns

Strategy: validation

Validate before calling

String s = str.substring(off, off + len);
if (Bytes.C64.length() > 64 && s.length() % 4 != 0) {
    StringBuilder sb = new StringBuilder(s);
    while (sb.length() % 4 != 0) sb.append('=');
    s = sb.toString();
    off = 0; len = s.length();
}
byte[] b = Bytes.base642bytes(s, off, len, Bytes.C64);

Type guard

static boolean isPaddedBase64(String s) {
    return s.length() % 4 == 0;
}

Try / catch

try {
    byte[] b = Bytes.base642bytes(str, off, len, Bytes.C64);
} catch (IllegalArgumentException e) {
    String s = str.substring(off, off + len);
    while (s.length() % 4 != 0) s += "=";
    byte[] b = Bytes.base642bytes(s, 0, s.length(), Bytes.C64);
}

Prevention

When it happens

Trigger: Decoding with a padded alphabet (e.g. the default C64 which has '=' at index 64) a string whose length is not a multiple of 4, e.g. 'ZHViYm8' (7 chars) instead of 'ZHViYm8=' (8).

Common situations: Padding '=' characters were stripped (URL/cookie transport that drops '='); concatenation of Base64 fragments without re-padding; config/property value trimmed of trailing '='.

Related errors


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