MyCATApache/Mycat-Server · error · IllegalArgumentException

String length must be a multiple of four.

Error message

String length must be a multiple of four.

What it means

DecryptUtil's internal Base64 decoder (Sun-style alternate alphabet support) requires the input string length to be an exact multiple of 4; each 4-character group encodes 3 bytes. It throws IllegalArgumentException('String length must be a multiple of four.') when the string is truncated or has stray characters.

Solutions

  1. Re-copy the full Base64 value and check its length is a multiple of 4
  2. Add missing '=' padding: append 1 or 2 '=' so the length becomes a multiple of 4
  3. Regenerate the encoded value from the source data with a standard Base64 encoder
  4. If data is URL-safe Base64, convert '-'/'+' and padding to the alphabet this decoder expects before calling

Example fix

// before
String s = "YWJjZGVmZw"; // length 10, invalid
// after
String s = "YWJjZGVmZw=="; // padded to 12, valid
Defensive patterns

Strategy: validation

Validate before calling

static boolean isDecodableBase64(String s){
    return s != null && s.length()%4==0 && s.matches("[A-Za-z0-9+/]+=*");
}

Try / catch

try { byte[] b = DecryptUtil.base64ToByteArray(s); }
catch (IllegalArgumentException e) { throw new IllegalArgumentException("truncated Base64: len=" + (s==null?-1:s.length()), e); }

Prevention

When it happens

Trigger: Calling base64ToByteArray (public via decrypt flows) with a Base64 string whose length % 4 != 0 — typically truncated copy/paste, or missing/extra '=' padding characters.

Common situations: Passwords or keys copied from email/terminal with dropped trailing characters; padding '=' stripped by a templating system; concatenating fragments of encoded values.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/41ee76fc740ba2df. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/util/DecryptUtil.java:335

	        return base64ToByteArray(s, false);
	    }

	    /**
	     * Translates the specified "alternate representation" Base64 string into a byte array.
	     * 
	     * @throw IllegalArgumentException or ArrayOutOfBoundsException if <tt>s</tt> is not a valid alternate
	     * representation Base64 string.
	     */
	    public static byte[] altBase64ToByteArray(String s) {
	        return base64ToByteArray(s, true);
	    }

	    private static byte[] base64ToByteArray(String s, boolean alternate) {
	        byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
	        int sLen = s.length();
	        int numGroups = sLen / 4;
	        if (4 * numGroups != sLen) {
	            throw new IllegalArgumentException("String length must be a multiple of four.");
	        }
	        int missingBytesInLastGroup = 0;
	        int numFullGroups = numGroups;
	        if (sLen != 0) {
	            if (s.charAt(sLen - 1) == '=') {
	                missingBytesInLastGroup++;
	                numFullGroups--;
	            }
	            if (s.charAt(sLen - 2) == '=') {
	                missingBytesInLastGroup++;
	            }
	        }
	        byte[] result = new byte[3 * numGroups - missingBytesInLastGroup];

	        // Translate all full groups from base64 to byte array elements
	        int inCursor = 0, outCursor = 0;
	        for (int i = 0; i < numFullGroups; i++) {
	            int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);

View on GitHub (pinned to 65f8d8beb7)