{"record":{"id":"3b91f2f693ea92ae","repo":"spring-projects/spring-security","slug":"invalid-client-3b91f2","errorCode":"invalid_client","errorMessage":"Client authentication failed: client_id","messagePattern":"Client authentication failed: client_id","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":null,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/X509ClientCertificateAuthenticationProvider.java","lineNumber":95,"sourceCode":"\t\tAssert.notNull(authorizationService, \"authorizationService cannot be null\");\n\t\tthis.registeredClientRepository = registeredClientRepository;\n\t\tthis.codeVerifierAuthenticator = new CodeVerifierAuthenticator(authorizationService);\n\t}\n\n\t@Override\n\tpublic @Nullable Authentication authenticate(Authentication authentication) throws AuthenticationException {\n\t\tOAuth2ClientAuthenticationToken clientAuthentication = (OAuth2ClientAuthenticationToken) authentication;\n\n\t\tif (!ClientAuthenticationMethod.TLS_CLIENT_AUTH.equals(clientAuthentication.getClientAuthenticationMethod())\n\t\t\t\t&& !ClientAuthenticationMethod.SELF_SIGNED_TLS_CLIENT_AUTH\n\t\t\t\t\t.equals(clientAuthentication.getClientAuthenticationMethod())) {\n\t\t\treturn null;\n\t\t}\n\n\t\tString clientId = clientAuthentication.getPrincipal().toString();\n\t\tRegisteredClient registeredClient = this.registeredClientRepository.findByClientId(clientId);\n\t\tif (registeredClient == null) {\n\t\t\tthrow invalidClient(OAuth2ParameterNames.CLIENT_ID);\n\t\t}\n\n\t\tif (this.logger.isTraceEnabled()) {\n\t\t\tthis.logger.trace(\"Retrieved registered client\");\n\t\t}\n\n\t\tif (!registeredClient.getClientAuthenticationMethods()\n\t\t\t.contains(clientAuthentication.getClientAuthenticationMethod())) {\n\t\t\tthrow invalidClient(\"authentication_method\");\n\t\t}\n\n\t\tif (!(clientAuthentication.getCredentials() instanceof X509Certificate[])) {\n\t\t\tthrow invalidClient(\"credentials\");\n\t\t}\n\n\t\tOAuth2ClientAuthenticationContext authenticationContext = OAuth2ClientAuthenticationContext\n\t\t\t.with(clientAuthentication)\n\t\t\t.registeredClient(registeredClient)","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/X509ClientCertificateAuthenticationProvider.java#L77-L113","documentation":"X509ClientCertificateAuthenticationProvider.authenticate handles mTLS client authentication (RFC 8705) with the tls_client_auth method. It resolves the client_id from the client authentication token; if RegisteredClientRepository.findClientId returns no client, it throws invalid_client with message 'Client authentication failed: client_id'.","triggerScenarios":"An mTLS token request presenting a client certificate whose client_id (from the authentication principal) has no matching RegisteredClient in the repository.","commonSituations":"tls_client_auth client not registered on the server; certificate issued for a client id that was renamed or removed; requests routed to an environment lacking the client registration; misconfigured reverse proxy not passing the certificate-derived client id.","solutions":["Register the client with the exact client_id and ClientAuthenticationMethod.TLS_CLIENT_AUTH in the RegisteredClientRepository.","Verify the certificate's client identity maps to the registered client_id (check the proxy/extractor that builds the authentication principal).","Confirm both sides use the same environment's client registry.","Enable trace logging to see the received client_id value."],"exampleFix":"// before: client unregistered\n// after: register tls_client_auth client\nRegisteredClient.create().clientId(\"mtls-client\")\n    .clientAuthenticationMethod(ClientAuthenticationMethod.TLS_CLIENT_AUTH)\n    .clientSettings(ClientSettings.builder()\n        .x509CertificateSubjectDN(\"CN=mtls-client,OU=Acme,O=Acme,C=US\")\n        .build())\n    .build();","handlingStrategy":"validation","validationCode":"RegisteredClient rc = registeredClientRepository.findByClientId(clientId);\nif (rc == null) { throw new IllegalStateException(\"mtls client not registered: \" + clientId); }","typeGuard":null,"tryCatchPattern":"catch (OAuth2AuthenticationException e) { if (\"invalid_client\".equals(e.getError().getErrorCode())) { registerTlsClientAuthClient(); } }","preventionTips":["Register tls_client_auth clients with TLS_CLIENT_AUTH method and subject DN","Verify certificate-to-client_id mapping in the proxy","Sync registrations across environments"],"tags":["oauth2","mtls","client-authentication","invalid-client"],"backgroundTag":"authentication-required","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"}