spring-projects/spring-security · warning

FilterSecurityInterceptor is configured to reject public…

Error message

FilterSecurityInterceptor is configured to reject public invocations. Your login page may not be accessible.

What it means

During validation, DefaultFilterChainValidator checks whether the configured login page URL would be reachable. If FilterSecurityInterceptor has rejectPublicInvocations=true and no ConfigAttributes are defined for the login request, the login page would be denied, so this warning is logged to alert the developer that login may be inaccessible.

Solutions

  1. Add an explicit intercept rule permitting the login page (e.g. IS_AUTHENTICATED_ANONYMOUSLY/permitAll) for its URL
  2. Set rejectPublicInvocations(false) on the FilterSecurityInterceptor
  3. Migrate to authorizeHttpRequests with .requestMatchers("/login").permitAll(), which avoids the interceptor entirely

Example fix

// before
interceptor.setRejectPublicInvocations(true); // login page has no attributes
// after
http.authorizeHttpRequests(auth -> auth
  .requestMatchers("/login").permitAll()
  .anyRequest().authenticated());
Defensive patterns

Strategy: validation

Validate before calling

// Verify public URLs are explicitly permitted before enabling rejectPublicInvocations
boolean loginCovered = metadataSource.getAttributes(new FilterInvocation("/login", "GET", null)) != null;
if (rejectPublicInvocations && !loginCovered) { permitLoginUrl(); }

Prevention

When it happens

Trigger: checkLoginPageIsPublic finds no attributes for the login page URL in the FilterInvocationSecurityMetadataSource while the FilterSecurityInterceptor is configured to reject public (unsecured) invocations.

Common situations: Setting rejectPublicInvocations(true) on FilterSecurityInterceptor without explicitly defining access rules for the login/error pages; strict 'deny everything not explicitly permitted' configs.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/1a5f4b10000a3f46. Report an issue: GitHub.

Appendix: source

Thrown at config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java:315

		private static boolean isFilterSecurityInterceptor(Filter filter) {
			return filter instanceof FilterSecurityInterceptor;
		}

		private static Class<FilterSecurityInterceptor> getFilterSecurityInterceptorClass() {
			return FilterSecurityInterceptor.class;
		}

		private static Boolean checkLoginPageIsPublic(List<Filter> filters, HttpServletRequest loginRequest) {
			FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
			if (authorizationInterceptor == null) {
				return null;
			}
			FilterInvocationSecurityMetadataSource fids = authorizationInterceptor.getSecurityMetadataSource();
			Collection<ConfigAttribute> attributes = fids.getAttributes(loginRequest);
			if (attributes == null) {
				logger.debug("No access attributes defined for login page URL");
				if (authorizationInterceptor.isRejectPublicInvocations()) {
					logger.warn("FilterSecurityInterceptor is configured to reject public invocations."
							+ " Your login page may not be accessible.");
				}
				return true;
			}
			return false;
		}

		private static Supplier<Boolean> getAnonymousCheck(List<Filter> filters, HttpServletRequest loginRequest,
				AnonymousAuthenticationToken token) {
			FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
			if (authorizationInterceptor == null) {
				return null;
			}
			return () -> {
				FilterInvocationSecurityMetadataSource source = authorizationInterceptor.getSecurityMetadataSource();
				Collection<ConfigAttribute> attributes = source.getAttributes(loginRequest);
				try {
					authorizationInterceptor.getAccessDecisionManager().decide(token, loginRequest, attributes);

View on GitHub (pinned to 96852e8860)