{"record":{"id":"a56127fd37acdcc8","repo":"spring-projects/spring-security","slug":"invalid-request-a56127","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/ClientSecretPostAuthenticationConverter.java","lineNumber":63,"sourceCode":" * @see OAuth2ClientAuthenticationFilter\n * @see <a target=\"_blank\" href=\n * \"https://tools.ietf.org/html/rfc6749#section-2.3.1\">Section 2.3.1 Client Password</a>\n */\npublic final class ClientSecretPostAuthenticationConverter implements AuthenticationConverter {\n\n\t@Override\n\tpublic @Nullable Authentication convert(HttpServletRequest request) {\n\t\tMultiValueMap<String, String> parameters = OAuth2EndpointUtils.getFormParameters(request);\n\n\t\t// client_id (REQUIRED)\n\t\tString clientId = parameters.getFirst(OAuth2ParameterNames.CLIENT_ID);\n\t\tif (!StringUtils.hasText(clientId)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tList<String> clientIdParams = parameters.get(OAuth2ParameterNames.CLIENT_ID);\n\t\tif (clientIdParams == null || clientIdParams.size() != 1) {\n\t\t\tthrow new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_REQUEST);\n\t\t}\n\n\t\t// client_secret (REQUIRED)\n\t\tString clientSecret = parameters.getFirst(OAuth2ParameterNames.CLIENT_SECRET);\n\t\tif (!StringUtils.hasText(clientSecret)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tList<String> clientSecretParams = parameters.get(OAuth2ParameterNames.CLIENT_SECRET);\n\t\tif (clientSecretParams == null || clientSecretParams.size() != 1) {\n\t\t\tthrow new OAuth2AuthenticationException(OAuth2ErrorCodes.INVALID_REQUEST);\n\t\t}\n\n\t\tMap<String, Object> additionalParameters = OAuth2EndpointUtils\n\t\t\t.getParametersIfMatchesAuthorizationCodeGrantRequest(request, OAuth2ParameterNames.CLIENT_ID,\n\t\t\t\t\tOAuth2ParameterNames.CLIENT_SECRET);\n\n\t\treturn new OAuth2ClientAuthenticationToken(clientId, ClientAuthenticationMethod.CLIENT_SECRET_POST,","sourceCodeStart":45,"sourceCodeEnd":81,"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/ClientSecretPostAuthenticationConverter.java#L45-L81","documentation":"Thrown by ClientSecretPostAuthenticationConverter.convert() when the client_id form parameter is present but was supplied more than once (or zero times despite clientId being detected). RFC 6749 requires each parameter exactly once, so a duplicate client_id in the token request body is rejected as invalid_request.","triggerScenarios":"POSTing a token request whose body contains client_id twice, e.g. both in a query string merged into parameters and in the form body, or repeated form fields.","commonSituations":"Client libraries appending client_id to the URL while also including it in the form body; form builders that add the field twice; combining Spring's default parameter handling with manually added parameters.","solutions":["Send client_id exactly once in the request body; remove duplicate form fields.","Remove client_id from the query string if it is already in the POST body.","Review client code for double-adding the parameter when building the MultiValueMap.","Log the outgoing form body before the request to confirm a single client_id entry."],"exampleFix":"// before\nform.add(\"client_id\", clientId);\nform.add(\"client_id\", clientId); // duplicate\n// after\nform.set(\"client_id\", clientId); // or add exactly once","handlingStrategy":"validation","validationCode":"MultiValueMap<String, String> dedupe(MultiValueMap<String, String> form) {\n    LinkedMultiValueMap<String, String> out = new LinkedMultiValueMap<>();\n    form.forEach((k, v) -> out.set(k, v.get(v.size() - 1)));\n    return out;\n}","typeGuard":null,"tryCatchPattern":"try { tokenResponse = rest.post().body(form).retrieve().toEntity(...); }\ncatch (HttpClientErrorException e) {\n    if (e.getResponseBodyAsString().contains(\"invalid_request\")) { log.error(\"Check for duplicate client_id in body/query\"); }\n    throw e;\n}","preventionTips":["Use map.set() instead of add() for singleton OAuth2 parameters.","Never place client_id in both query string and form body."],"tags":["oauth2","client-authentication","request-parameters","duplicate-parameter"],"backgroundTag":"duplicate-parameter","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}