{"record":{"id":"088e322131fdf578","repo":"spring-projects/spring-security","slug":"invalid-basic-authentication-token","errorCode":null,"errorMessage":"Invalid basic authentication token","messagePattern":"Invalid 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":96,"sourceCode":"\t@Override\n\tpublic @Nullable UsernamePasswordAuthenticationToken convert(HttpServletRequest request) {\n\t\tString header = request.getHeader(HttpHeaders.AUTHORIZATION);\n\t\tif (header == null) {\n\t\t\treturn null;\n\t\t}\n\t\theader = header.trim();\n\t\tif (!StringUtils.startsWithIgnoreCase(header, AUTHENTICATION_SCHEME_BASIC)) {\n\t\t\treturn null;\n\t\t}\n\t\tif (header.equalsIgnoreCase(AUTHENTICATION_SCHEME_BASIC)) {\n\t\t\tthrow new BadCredentialsException(\"Empty basic authentication token\");\n\t\t}\n\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();","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/authentication/www/BasicAuthenticationConverter.java#L78-L114","documentation":"After Base64-decoding the Basic auth payload, convert expects 'username:password' — the colon delimiter is mandatory per RFC 7617. If the decoded string contains no ':', BadCredentialsException('Invalid basic authentication token') is thrown because the credentials are structurally invalid.","triggerScenarios":"convert decodes the Base64 portion of the Authorization header and token.indexOf(\":\") returns -1 — e.g. the Base64 value encodes only a username, or arbitrary garbage that decodes without a colon.","commonSituations":"Clients Base64-encoding the username only, or forgetting the ':' separator; corrupted/truncated Authorization headers; tests hard-coding incorrectly encoded values; non-UTF8 encoded payloads mangled in transit.","solutions":["Encode credentials as Base64(username + \":\" + password) per RFC 7617","Verify the client library's basic-auth helper is used instead of manual encoding","Check header integrity through proxies (no truncation/re-encoding)","Log the decoded shape (never the credentials) to confirm the missing delimiter"],"exampleFix":"// before\nString encoded = Base64.getEncoder().encodeToString(user.getBytes()); // missing ':'\n// after\nString encoded = Base64.getEncoder().encodeToString((user + \":\" + password).getBytes(UTF_8));","handlingStrategy":"validation","validationCode":"String decoded = new String(Base64.getDecoder().decode(base64Part), StandardCharsets.UTF_8);\nif (!decoded.contains(\":\")) {\n    response.sendError(401, \"Malformed basic auth payload; expected username:password\");\n    return;\n}","typeGuard":"boolean isWellFormedBasicPayload(String decoded) {\n    return decoded != null && decoded.indexOf(':') >= 0;\n}","tryCatchPattern":"try {\n    Authentication a = converter.convert(request);\n} catch (BadCredentialsException e) {\n    response.setHeader(\"WWW-Authenticate\", \"Basic realm=\\\"app\\\"\");\n    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);\n}","preventionTips":["Use a standard basic-auth helper instead of hand-rolled Base64 encoding","Always include the ':' separator between username and password","Use UTF-8 consistently when encoding credentials","Unit-test credential encoding end-to-end against the server"],"tags":["spring-security","basic-auth","http-header","format"],"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"}