{"record":{"id":"ed52791f98a988e8","repo":"spring-projects/spring-security","slug":"no-pre-authenticated-principal-found-in-request","errorCode":null,"errorMessage":"No pre-authenticated principal found in request.","messagePattern":"No pre-authenticated principal found in request\\.","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedAuthenticationProvider.java","lineNumber":95,"sourceCode":"\t\tAssert.notNull(this.preAuthenticatedUserDetailsService, \"An AuthenticationUserDetailsService must be set\");\n\t}\n\n\t/**\n\t * Authenticate the given PreAuthenticatedAuthenticationToken.\n\t * <p>\n\t * If the principal contained in the authentication object is null, the request will\n\t * be ignored to allow other providers to authenticate it.\n\t */\n\t@Override\n\tpublic @Nullable Authentication authenticate(Authentication authentication) throws AuthenticationException {\n\t\tif (!supports(authentication.getClass())) {\n\t\t\treturn null;\n\t\t}\n\t\tlogger.debug(LogMessage.format(\"PreAuthenticated authentication request: %s\", authentication));\n\t\tif (authentication.getPrincipal() == null) {\n\t\t\tlogger.debug(\"No pre-authenticated principal found in request.\");\n\t\t\tif (this.throwExceptionWhenTokenRejected) {\n\t\t\t\tthrow new BadCredentialsException(\"No pre-authenticated principal found in request.\");\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\tif (authentication.getCredentials() == null) {\n\t\t\tlogger.debug(\"No pre-authenticated credentials found in request.\");\n\t\t\tif (this.throwExceptionWhenTokenRejected) {\n\t\t\t\tthrow new BadCredentialsException(\"No pre-authenticated credentials found in request.\");\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\tUserDetails userDetails = this.preAuthenticatedUserDetailsService\n\t\t\t.loadUserDetails((PreAuthenticatedAuthenticationToken) authentication);\n\t\tthis.userDetailsChecker.check(userDetails);\n\t\tCollection<GrantedAuthority> authorities = new LinkedHashSet<>(userDetails.getAuthorities());\n\t\tauthorities.addAll(this.grantedAuthoritySupplier.get());\n\t\tPreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(userDetails,\n\t\t\t\tauthentication.getCredentials(), authorities);\n\t\tresult.setDetails(authentication.getDetails());","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedAuthenticationProvider.java#L77-L113","documentation":"PreAuthenticatedAuthenticationProvider.authenticate() rejects any incoming PreAuthenticatedAuthenticationToken whose principal is null. Because there is no way to authenticate a request without an identity, the provider either throws BadCredentialsException (when throwExceptionWhenTokenRejected is true) or silently returns null, letting the ProviderManager try the next provider.","triggerScenarios":"Calling authenticate() with a PreAuthenticatedAuthenticationToken built via new PreAuthenticatedAuthenticationToken(null, credentials) or a token whose details mapper produced no principal, while throwExceptionWhenTokenRejected=true.","commonSituations":"A header/attribute-extraction filter (e.g. RequestHeaderAuthenticationFilter) is deployed behind a proxy that strips the identity header, so the token is created with a null principal; a custom AuthenticationUserDetailsSsoService/filter returns null when the SSO attribute is absent; unit tests construct a token without a principal and enable throwExceptionWhenTokenRejected.","solutions":["Ensure the pre-auth source (header, request attribute, J2EE principal) is actually present before the token reaches the provider — verify proxies/load balancers forward the identity header.","Set throwExceptionWhenTokenRejected=false (setRejectWhenTokenRejected) if you want the provider to pass instead of throwing and other providers to be tried.","Fix the upstream filter config: confirm principalRequestHeader/principalEnvironmentVariable matches the header actually sent by your SSO layer.","In tests, construct the token with a non-null principal: new PreAuthenticatedAuthenticationToken(\"user\", \"creds\")."],"exampleFix":"// before\nprovider.setThrowExceptionWhenTokenRejected(true); // hard failure on missing principal\n// after\nprovider.setThrowExceptionWhenTokenRejected(false); // skip provider, no exception","handlingStrategy":"validation","validationCode":"if (token.getPrincipal() == null) {\n    throw new IllegalStateException(\"Pre-auth token has no principal; check upstream header/filter config\");\n}\nprovider.authenticate(token);","typeGuard":"boolean hasPrincipal = (auth != null && auth.getPrincipal() != null);","tryCatchPattern":null,"preventionTips":["Keep throwExceptionWhenTokenRejected=false unless you explicitly want fail-fast behavior","Verify proxies forward identity headers before the filter chain","Unit-test your pre-auth filter to assert principal/credentials are never null"],"tags":["spring-security","preauth","bad-credentials","authentication"],"backgroundTag":"missing-credentials","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"}