{"record":{"id":"41ee76fc740ba2df","repo":"MyCATApache/Mycat-Server","slug":"string-length-must-be-a-multiple-of-four","errorCode":null,"errorMessage":"String length must be a multiple of four.","messagePattern":"String length must be a multiple of four\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/util/DecryptUtil.java","lineNumber":335,"sourceCode":"\t        return base64ToByteArray(s, false);\n\t    }\n\n\t    /**\n\t     * Translates the specified \"alternate representation\" Base64 string into a byte array.\n\t     * \n\t     * @throw IllegalArgumentException or ArrayOutOfBoundsException if <tt>s</tt> is not a valid alternate\n\t     * representation Base64 string.\n\t     */\n\t    public static byte[] altBase64ToByteArray(String s) {\n\t        return base64ToByteArray(s, true);\n\t    }\n\n\t    private static byte[] base64ToByteArray(String s, boolean alternate) {\n\t        byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);\n\t        int sLen = s.length();\n\t        int numGroups = sLen / 4;\n\t        if (4 * numGroups != sLen) {\n\t            throw new IllegalArgumentException(\"String length must be a multiple of four.\");\n\t        }\n\t        int missingBytesInLastGroup = 0;\n\t        int numFullGroups = numGroups;\n\t        if (sLen != 0) {\n\t            if (s.charAt(sLen - 1) == '=') {\n\t                missingBytesInLastGroup++;\n\t                numFullGroups--;\n\t            }\n\t            if (s.charAt(sLen - 2) == '=') {\n\t                missingBytesInLastGroup++;\n\t            }\n\t        }\n\t        byte[] result = new byte[3 * numGroups - missingBytesInLastGroup];\n\n\t        // Translate all full groups from base64 to byte array elements\n\t        int inCursor = 0, outCursor = 0;\n\t        for (int i = 0; i < numFullGroups; i++) {\n\t            int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/util/DecryptUtil.java#L317-L353","documentation":"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.","triggerScenarios":"Calling base64ToByteArray (public via decrypt flows) with a Base64 string whose length % 4 != 0 — typically truncated copy/paste, or missing/extra '=' padding characters.","commonSituations":"Passwords or keys copied from email/terminal with dropped trailing characters; padding '=' stripped by a templating system; concatenating fragments of encoded values.","solutions":["Re-copy the full Base64 value and check its length is a multiple of 4","Add missing '=' padding: append 1 or 2 '=' so the length becomes a multiple of 4","Regenerate the encoded value from the source data with a standard Base64 encoder","If data is URL-safe Base64, convert '-'/'+' and padding to the alphabet this decoder expects before calling"],"exampleFix":"// before\nString s = \"YWJjZGVmZw\"; // length 10, invalid\n// after\nString s = \"YWJjZGVmZw==\"; // padded to 12, valid","handlingStrategy":"validation","validationCode":"static boolean isDecodableBase64(String s){\n    return s != null && s.length()%4==0 && s.matches(\"[A-Za-z0-9+/]+=*\");\n}","typeGuard":null,"tryCatchPattern":"try { byte[] b = DecryptUtil.base64ToByteArray(s); }\ncatch (IllegalArgumentException e) { throw new IllegalArgumentException(\"truncated Base64: len=\" + (s==null?-1:s.length()), e); }","preventionTips":["Assert input length % 4 == 0 before decoding","Never truncate Base64 strings in logs/templates; store them intact","Re-encode with a standard encoder rather than hand-editing encoded values","Strip whitespace before decoding so only genuine truncation fails"],"tags":["java","base64","decoding"],"backgroundTag":"invalid-argument-format","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}