{"record":{"id":"913ad884c6cc2871","repo":"spring-projects/spring-security","slug":"a-filter-chain-that-matches-any-request-anyreque","errorCode":null,"errorMessage":"A filter chain that matches any request [{anyRequestFilterChain}] has already been configured, which means that this filter chain [{chain}] will never get invoked. Please use `HttpSecurity#securityMatcher` to ensure that there is only one filter chain configured for 'any request' and that the 'any request' filter chain is published last.","messagePattern":"A filter chain that matches any request \\[(.+?)\\] has already been configured, which means that this filter chain \\[(.+?)\\] will never get invoked\\. Please use `HttpSecurity#securityMatcher` to ensure that there is only one filter chain configured for 'any request' and that the 'any request' filter chain is published last\\.","errorType":"exception","errorClass":"UnreachableFilterChainException","httpStatus":null,"severity":"error","filePath":"config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidator.java","lineNumber":63,"sourceCode":"\n\tprivate final Log logger = LogFactory.getLog(getClass());\n\n\t@Override\n\tpublic void validate(FilterChainProxy filterChainProxy) {\n\t\tList<SecurityFilterChain> chains = filterChainProxy.getFilterChains();\n\t\tcheckForAnyRequestRequestMatcher(chains);\n\t\tcheckForDuplicateMatchers(chains);\n\t\tcheckAuthorizationFilters(chains);\n\t}\n\n\tprivate void checkForAnyRequestRequestMatcher(List<SecurityFilterChain> chains) {\n\t\tDefaultSecurityFilterChain anyRequestFilterChain = null;\n\t\tfor (SecurityFilterChain chain : chains) {\n\t\t\tif (anyRequestFilterChain != null) {\n\t\t\t\tString message = \"A filter chain that matches any request [\" + anyRequestFilterChain\n\t\t\t\t\t\t+ \"] has already been configured, which means that this filter chain [\" + chain\n\t\t\t\t\t\t+ \"] will never get invoked. Please use `HttpSecurity#securityMatcher` to ensure that there is only one filter chain configured for 'any request' and that the 'any request' filter chain is published last.\";\n\t\t\t\tthrow new UnreachableFilterChainException(message, anyRequestFilterChain, chain);\n\t\t\t}\n\t\t\tif (chain instanceof DefaultSecurityFilterChain defaultChain) {\n\t\t\t\tif (defaultChain.getRequestMatcher() instanceof AnyRequestMatcher) {\n\t\t\t\t\tanyRequestFilterChain = defaultChain;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void checkForDuplicateMatchers(List<SecurityFilterChain> chains) {\n\t\tDefaultSecurityFilterChain filterChain = null;\n\t\tfor (SecurityFilterChain chain : chains) {\n\t\t\tif (filterChain != null) {\n\t\t\t\tif (chain instanceof DefaultSecurityFilterChain defaultChain) {\n\t\t\t\t\tif (defaultChain.getRequestMatcher().equals(filterChain.getRequestMatcher())) {\n\t\t\t\t\t\tthrow new UnreachableFilterChainException(\n\t\t\t\t\t\t\t\t\"The FilterChainProxy contains two filter chains using the\" + \" matcher \"\n\t\t\t\t\t\t\t\t\t\t+ defaultChain.getRequestMatcher(),","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidator.java#L45-L81","documentation":"WebSecurityFilterChainValidator validates the published SecurityFilterChain list. checkForAnyRequestRequestMatcher throws UnreachableFilterChainException when a chain that matches any request (anyRequest()) is configured before another chain, because the earlier any-request chain will swallow every request and later chains can never run.","triggerScenarios":"Publishing two or more SecurityFilterChain beans where one uses anyRequest() and is not the last chain; multiple @SecurityFilterChain / WebSecurityConfigurerAdapter beans where the anyRequest chain is ordered first; misused @Order on filter chain beans.","commonSituations":"Microservice setups with multiple security configurations (API + actuator + default); copying a default anyRequest chain from samples alongside specialized chains; Spring Boot 5.8+ style multiple SecurityFilterChain beans with wrong @Order values.","solutions":["Order the chains so the anyRequest() chain is last (give it the lowest-priority @Order, e.g. @Order(Ordered.LOWEST_PRECEDENCE))","Narrow the overly-broad chain with securityMatcher(\"/specific/**\") instead of anyRequest()","Remove the duplicate anyRequest chain if it is redundant"],"exampleFix":"// before\n@Order(1)\nSecurityFilterChain anyChain(HttpSecurity http) { http.authorizeHttpRequests(a -> a.anyRequest().authenticated()); ... }\n// after\n@Order(Ordered.LOWEST_PRECEDENCE)\nSecurityFilterChain anyChain(HttpSecurity http) { http.authorizeHttpRequests(a -> a.anyRequest().authenticated()); ... }","handlingStrategy":"validation","validationCode":"// before publishing chains, assert anyRequest chains are last\nSecurityFilterChain last = chains.get(chains.size() - 1);\nfor (int i = 0; i < chains.size() - 1; i++) {\n    if (matchesAnyRequest(chains.get(i))) {\n        throw new IllegalStateException(\"anyRequest() chain must be the last published chain\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    webSecurity.build();\n} catch (UnreachableFilterChainException e) {\n    logger.error(\"Reorder your SecurityFilterChain beans: anyRequest chain must be last; offending: \" + e.getMessage());\n    throw e;\n}","preventionTips":["Give the anyRequest() chain @Order(Ordered.LOWEST_PRECEDENCE) and specific chains lower order values","Use securityMatcher(\"/api/**\") instead of anyRequest() on specialized chains","Review all SecurityFilterChain beans when adding a new one; check ordering and matcher overlap"],"tags":["spring-security","filter-chain","security-matcher","configuration"],"backgroundTag":"conflicting-config-options","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"}