{"record":{"id":"85e8ce54c59a6d06","repo":"spring-projects/spring-security","slug":"invalid-request-85e8ce","errorCode":"invalid_request","errorMessage":"invalid_request","messagePattern":"invalid_request","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/ClientSecretBasicAuthenticationConverter.java","lineNumber":64,"sourceCode":" * @see OAuth2ClientAuthenticationToken\n * @see OAuth2ClientAuthenticationFilter\n */\npublic final class ClientSecretBasicAuthenticationConverter implements AuthenticationConverter {\n\n\t@Override\n\tpublic @Nullable Authentication 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\n\t\tString[] parts = header.split(\"\\\\s\");\n\t\tif (!parts[0].equalsIgnoreCase(\"Basic\")) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (parts.length != 2) {\n\t\t\tthrow new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_REQUEST);\n\t\t}\n\n\t\tbyte[] decodedCredentials;\n\t\ttry {\n\t\t\tdecodedCredentials = Base64.getDecoder().decode(parts[1].getBytes(StandardCharsets.UTF_8));\n\t\t}\n\t\tcatch (IllegalArgumentException ex) {\n\t\t\tthrow new OAuth2AuthenticationException(new OAuth2Error(OAuth2ErrorCodes.INVALID_REQUEST), ex);\n\t\t}\n\n\t\tString credentialsString = new String(decodedCredentials, StandardCharsets.UTF_8);\n\t\tString[] credentials = credentialsString.split(\":\", 2);\n\t\tif (credentials.length != 2 || !StringUtils.hasText(credentials[0]) || !StringUtils.hasText(credentials[1])) {\n\t\t\tthrow new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_REQUEST);\n\t\t}\n\n\t\tString clientID;\n\t\tString clientSecret;","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/web/authentication/ClientSecretBasicAuthenticationConverter.java#L46-L82","documentation":"Thrown by ClientSecretBasicAuthenticationConverter.convert() when the Authorization header contains the 'Basic' scheme but is not composed of exactly two whitespace-separated parts (scheme + base64 credentials). The library treats a malformed Authorization header as an OAuth2 invalid_request per RFC 6749 section 2.3.1.","triggerScenarios":"Sending 'Authorization: Basic' with no credentials token, or extra tokens like 'Authorization: Basic abc extra', so parts.length != 2 after header.split(\"\\\\s\").","commonSituations":"HTTP clients that strip the base64 credential (proxy or interceptor mangling the header); manual header construction with a missing space or trailing junk; frameworks that fold multiple header values; clients putting 'Basic' in lowercase with concatenated credentials without whitespace.","solutions":["Build the Authorization header as 'Basic ' + Base64(clientId + ':' + clientSecret) with exactly one space between scheme and token.","Verify no proxy, gateway, or client interceptor rewrites or truncates the Authorization header.","If credentials are form-posted instead, use client_secret_post so the Basic converter is not invoked.","Catch OAuth2AuthenticationException on the client side and log the exact outgoing header to confirm its shape."],"exampleFix":"// before\nrequest.setHeader(\"Authorization\", \"Basic \" + clientId + \":\" + secret); // missing Base64 / wrong shape\n// after\nString token = Base64.getEncoder().encodeToString((clientId + \":\" + secret).getBytes(StandardCharsets.UTF_8));\nrequest.setHeader(\"Authorization\", \"Basic \" + token);","handlingStrategy":"validation","validationCode":"boolean validBasicHeader(String header) {\n    if (header == null || !header.startsWith(\"Basic \")) return false;\n    return header.split(\"\\\\s\").length == 2;\n}","typeGuard":null,"tryCatchPattern":"try { tokenResponse = client.token(request); }\ncatch (OAuth2AuthenticationException e) {\n    if (\"invalid_request\".equals(e.getError().getErrorCode())) { log.error(\"Malformed Authorization header\", e); }\n    throw e;\n}","preventionTips":["Always build Basic headers via a library helper rather than string concatenation.","Assert the header matches ^Basic\\s+\\S+$ in client-side tests before sending."],"tags":["oauth2","http-header","client-authentication","spring-security"],"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-14T16:17:12.679Z"}