{"record":{"id":"106f5f2ae41b0430","repo":"spring-projects/spring-security","slug":"failed-to-decode-basic-authentication-token","errorCode":null,"errorMessage":"Failed to decode basic authentication token","messagePattern":"Failed to decode basic authentication token","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":401,"severity":"error","filePath":"web/src/main/java/org/springframework/security/web/authentication/www/BasicAuthenticationConverter.java","lineNumber":109,"sourceCode":"\t\tbyte[] base64Token = header.substring(6).getBytes(StandardCharsets.UTF_8);\n\t\tbyte[] decoded = decode(base64Token);\n\t\tString token = new String(decoded, getCredentialsCharset(request));\n\t\tint delim = token.indexOf(\":\");\n\t\tif (delim == -1) {\n\t\t\tthrow new BadCredentialsException(\"Invalid basic authentication token\");\n\t\t}\n\t\tUsernamePasswordAuthenticationToken result = UsernamePasswordAuthenticationToken\n\t\t\t.unauthenticated(token.substring(0, delim), token.substring(delim + 1));\n\t\tresult.setDetails(this.authenticationDetailsSource.buildDetails(request));\n\t\treturn result;\n\t}\n\n\tprivate byte[] decode(byte[] base64Token) {\n\t\ttry {\n\t\t\treturn Base64.getDecoder().decode(base64Token);\n\t\t}\n\t\tcatch (IllegalArgumentException ex) {\n\t\t\tthrow new BadCredentialsException(\"Failed to decode basic authentication token\");\n\t\t}\n\t}\n\n\tprotected Charset getCredentialsCharset(HttpServletRequest request) {\n\t\treturn getCredentialsCharset();\n\t}\n\n}\n","sourceCodeStart":91,"sourceCodeEnd":118,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/authentication/www/BasicAuthenticationConverter.java#L91-L118","documentation":"BasicAuthenticationConverter.decode throws this BadCredentialsException when the credentials portion of the HTTP Basic 'Authorization' header cannot be Base64-decoded. Spring Security treats a malformed Base64 token as invalid credentials rather than a server error, so the request is rejected through the authentication failure path (typically 401).","triggerScenarios":"A request sends an 'Authorization: Basic <token>' header whose credentials segment is not valid Base64 (e.g. raw 'user:password' without Base64 encoding, truncated Base64, or characters outside the Base64 alphabet). Base64.getDecoder().decode(base64Token) throws IllegalArgumentException, which is converted into this exception.","commonSituations":"Clients hand-building the Authorization header without encoding; curl/scripts sending 'Basic user:password' literally; a proxy or middleware corrupting or truncating the header; tests using plaintext credentials; non-ASCII characters double-encoded incorrectly.","solutions":["Base64-encode the credentials on the client: 'Basic ' + base64(username + ':' + password) (e.g. curl -u user:password does this for you).","Log the raw Authorization header (minus secrets) to confirm what actually reaches the server; fix the client or intermediate proxy that is mangling it.","If you control the bytes, ensure you use standard Base64 (not URL-safe or mime variants that the strict decoder rejects).","Client-side, catch org.springframework.security.authentication.BadCredentialsException / AuthenticationException and return 401 rather than retrying."],"exampleFix":"// before (client)\nconnection.setRequestProperty(\"Authorization\", \"Basic \" + user + \":\" + password);\n// after\nString token = Base64.getEncoder().encodeToString((user + \":\" + password).getBytes(StandardCharsets.UTF_8));\nconnection.setRequestProperty(\"Authorization\", \"Basic \" + token);","handlingStrategy":"try-catch","validationCode":"String creds = header.startsWith(\"Basic \") ? header.substring(6) : null;\nboolean isBase64 = creds != null && creds.matches(\"[A-Za-z0-9+/=\\r\\n]+\") && creds.length() % 4 == 0;\nif (!isBase64) throw new IllegalArgumentException(\"Authorization credentials are not valid Base64\");","typeGuard":"boolean isValidBase64(String s) {\n    try { java.util.Base64.getDecoder().decode(s); return true; }\n    catch (IllegalArgumentException e) { return false; }\n}","tryCatchPattern":"try {\n    authResult = filter.doFilter(request, response, chain);\n} catch (AuthenticationException e) {\n    // BadCredentialsException(\"Failed to decode basic authentication token\")\n    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, \"Malformed Basic credentials\");\n}","preventionTips":["Always Base64-encode 'username:password' with a standard encoder before building the Basic header","Use client libraries (curl -u, RestTemplate basic auth, requests auth=(u,p)) instead of hand-built headers","Encode UTF-8 explicitly to avoid charset-induced byte corruption","Integration-test the exact Authorization header bytes your client sends"],"tags":["spring-security","http-basic-auth","base64","bad-credentials"],"backgroundTag":"invalid-argument-format","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}