alibaba/nacos · error · IllegalArgumentException

Illegal base64 character: '{c}'

Error message

Illegal base64 character: '{c}'

What it means

Thrown by Base64Decode.ctoi() when the decode() method encounters a character that is not in the Base64 alphabet (A-Z, a-z, 0-9, +, /, =). The IALPHABET lookup table maps valid characters to their index and all others to -1; when ctoi sees a -1 it throws IllegalArgumentException naming the offending character. This is a custom Base64 decoder used in the Nacos auth plugin for processing tokens, credentials, or identity-related data.

Source

Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/utils/Base64Decode.java:130

            // Decode last 1-3 bytes (incl '=') into 1-3 bytes
            int i = 0;
            for (int j = 0; sIx <= eIx - pad; j++) {
                i |= ctoi(sArr[sIx++]) << (18 - j * 6);
            }
            
            for (int r = 16; d < len; r -= eight) {
                dArr[d++] = (byte) (i >> r);
            }
        }
        
        return dArr;
    }
    
    private static int ctoi(char c) {
        int i = c > IALPHABET_MAX_INDEX ? -1 : IALPHABET[c];
        if (i < 0) {
            String msg = "Illegal base64 character: '" + c + "'";
            throw new IllegalArgumentException(msg);
        }
        return i;
    }
    
}

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Inspect the exact character reported in the error message — it reveals what kind of data corruption occurred.
  2. If the input uses URL-safe base64, replace '-' with '+' and '_' with '/' before decoding, or use a decoder that supports the URL-safe variant.
  3. Strip whitespace and newlines from the input before decoding if the data came from a formatted source.
  4. Verify the upstream process that generated the base64 string is using standard base64 encoding (not hex, not URL-encoded, not raw text).

Example fix

// before: throws on URL-safe base64 or dirty input
byte[] decoded = Base64Decode.decode(token);

// after: sanitize and normalize input first
String sanitized = token.trim()
    .replace('-', '+')
    .replace('_', '/')
    .replaceAll("\\s", "");
byte[] decoded = Base64Decode.decode(sanitized);
Defensive patterns

Strategy: validation

Validate before calling

// Validate input is valid standard base64 before decoding
private static boolean isValidBase64(String input) {
    if (input == null || input.isEmpty()) return true;
    return input.matches("^[A-Za-z0-9+/]+={0,2}$");
}

if (!isValidBase64(input)) {
    // try URL-safe variant normalization
    input = input.replace('-', '+').replace('_', '/');
    if (!isValidBase64(input)) {
        throw new IllegalArgumentException("Input is not valid base64");
    }
}

Type guard

// Check if string is decodable base64 without throwing
public static boolean isBase64Decodable(String input) {
    if (input == null || input.isEmpty()) return true;
    for (char c : input.toCharArray()) {
        if (!(c >= 'A' && c <= 'Z') && !(c >= 'a' && c <= 'z')
            && !(c >= '0' && c <= '9') && c != '+' && c != '/' && c != '=') {
            return false;
        }
    }
    return true;
}

Try / catch

try {
    byte[] decoded = Base64Decode.decode(input);
} catch (IllegalArgumentException e) {
    // e.getMessage() contains the offending character
    log.warn("Base64 decode failed: {}", e.getMessage());
    throw e;
}

Prevention

When it happens

Trigger: Calling Base64Decode.decode(input) where input contains any character outside [A-Za-z0-9+/=], including whitespace, newlines in unexpected positions, URL-safe base64 characters (- or _), or completely corrupted/garbled data.

Common situations: A token or credential string that was URL-encoded but not decoded before base64 processing; URL-safe base64 variant (- and _ instead of + and /) fed to a standard decoder; corrupted or truncated token from a misconfigured client; a JSON string or raw text mistakenly passed where base64 was expected.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/4e4fb459211cc673. Report an issue: GitHub.