spring-projects/spring-security · warning
Anonymous access to the login page doesn't appear to be enab
Error message
Anonymous access to the login page doesn't appear to be enabled. This is almost certainly an error. Please check your configuration allows unauthenticated access to the configured login page. (Simulated access was rejected)
What it means
DefaultFilterChainValidator.checkLoginPageIsntProtected simulates anonymous access to the configured login page by replaying the filter chain with an AnonymousAuthenticationToken. If the simulated invocation is rejected, it warns that anonymous access to the login page is not actually enabled despite an anonymous filter being present, i.e. some filter or authorization rule still blocks unauthenticated users.
Source
Thrown at config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java:237
return;
}
if (checkLoginPageIsPublic(filters, loginRequest)) {
return;
}
AnonymousAuthenticationFilter anonymous = getFilter(AnonymousAuthenticationFilter.class, filters);
if (anonymous == null) {
this.logger.warn("The login page is being protected by the filter chain, but you don't appear to have"
+ " anonymous authentication enabled. This is almost certainly an error.");
return;
}
// Simulate an anonymous access with the supplied attributes.
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("key", anonymous.getPrincipal(),
anonymous.getAuthorities());
Supplier<Boolean> check = deriveAnonymousCheck(filters, loginRequest, token);
try {
boolean allowed = check.get();
if (!allowed) {
this.logger.warn("Anonymous access to the login page doesn't appear to be enabled. "
+ "This is almost certainly an error. Please check your configuration allows unauthenticated "
+ "access to the configured login page. (Simulated access was rejected)");
}
}
catch (Exception ex) {
// May happen legitimately if a filter-chain request matcher requires more
// request data than that provided
// by the dummy request used when creating the filter invocation. See SEC-1878
this.logger.info("Unable to check access to the login page to determine if anonymous access is allowed. "
+ "This might be an error, but can happen under normal circumstances.", ex);
}
}
private boolean checkLoginPageIsPublic(List<Filter> filters, HttpServletRequest loginRequest) {
if (USING_ACCESS) {
Boolean isPublic = AccessComponents.checkLoginPageIsPublic(filters, loginRequest);
if (isPublic != null) {
return isPublic;View on GitHub (pinned to 96852e8860)
Solutions
- Add requestMatchers("/login").permitAll() as the first authorization rule for the actual login URL.
- Check authorization rule ordering: permitAll entries must precede anyRequest().authenticated().
- Inspect custom filters for behavior that rejects anonymous tokens on the login path.
- Enable debug logging for FilterChainProxy and trace the simulated request to see which filter denies it.
Example fix
// before: login page still protected
http.authorizeHttpRequests(a -> a.anyRequest().authenticated())
.formLogin(f -> f.loginPage("/login"));
// after: explicit anonymous access
http.authorizeHttpRequests(a -> a.requestMatchers("/login").permitAll()
.anyRequest().authenticated())
.formLogin(f -> f.loginPage("/login")); Defensive patterns
Strategy: validation
Validate before calling
// simulated anonymous access in tests
mockMvc.perform(get("/login").anonymous())
.andExpect(status().isOk()); Prevention
- Place permitAll rules for public pages before anyRequest().authenticated().
- Keep custom filters no-op-friendly for anonymous tokens on public paths.
- Test each public URL with both anonymous and authenticated mocks.
- Enable org.springframework.security debug logging in dev to trace simulated access.
When it happens
Trigger: Calling validate() when the anonymous filter exists but deriveAnonymousCheck's simulated access is denied: an authorization rule or a filter (e.g. a strict RequestMatcher-based chain, CSRF, or custom filter) rejects the anonymous request to the login URL.
Common situations: Login page matched by a chained request matcher requiring authentication; permitAll rules placed after an anyRequest().authenticated() in the wrong order; custom filters throwing on anonymous tokens; multiple http blocks intercepting the login URL.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The login page is being protected by the filter chain, but y
- You are asking Spring Security to ignore %s. This is not rec
- It is not recommended to use authorizeRequests or FilterSecu
- Usage of authorizeRequests and FilterSecurityInterceptor are
- Access is denied
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/94befdadd1b33f9c.
Report an issue: GitHub.