spring-projects/spring-security · warning

Possible error: Filters at position <i> and <j> are both ins

Error message

Possible error: Filters at position <i> and <j> are both instances of <clazz.getName()>

What it means

DefaultFilterChainValidator.checkFilterStack scans the Spring Security filter chain and warns when two filters at different positions are both instances of the same configured filter class. Duplicate filters in the chain are almost always a configuration error that causes the filter to run twice (double authentication, double logging, order confusion). This is a logged warning, not an exception.

Source

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

		checkForDuplicates(BasicAuthenticationFilter.class, filters);
		checkForDuplicates(SecurityContextHolderAwareRequestFilter.class, filters);
		checkForDuplicates(JaasApiIntegrationFilter.class, filters);
		checkForDuplicates(ExceptionTranslationFilter.class, filters);
		if (USING_ACCESS) {
			checkForDuplicates(AccessComponents.getFilterSecurityInterceptorClass(), filters);
		}
		checkForDuplicates(AuthorizationFilter.class, filters);
	}

	private void checkForDuplicates(Class<? extends Filter> clazz, List<Filter> filters) {
		for (int i = 0; i < filters.size(); i++) {
			Filter f1 = filters.get(i);
			if (clazz.isAssignableFrom(f1.getClass())) {
				// Found the first one, check remaining for another
				for (int j = i + 1; j < filters.size(); j++) {
					Filter f2 = filters.get(j);
					if (clazz.isAssignableFrom(f2.getClass())) {
						this.logger.warn("Possible error: Filters at position " + i + " and " + j + " are both "
								+ "instances of " + clazz.getName());
						return;
					}
				}
			}
		}
	}

	/*
	 * Checks for the common error of having a login page URL protected by the security
	 * interceptor
	 */
	private void checkLoginPageIsntProtected(FilterChainProxy fcp, List<Filter> filterStack) {
		ExceptionTranslationFilter exceptions = getFilter(ExceptionTranslationFilter.class, filterStack);
		if (exceptions == null
				|| !(exceptions.getAuthenticationEntryPoint() instanceof LoginUrlAuthenticationEntryPoint)) {
			return;
		}

View on GitHub (pinned to 96852e8860)

Solutions

  1. Remove the manual registration if Spring Security already inserts that filter by default.
  2. Use addFilterBefore/addFilterAfter with a distinct custom class instead of re-registering a stock filter.
  3. Log the full filter chain (enable debug logging for FilterChainProxy) and delete the duplicate entry.
  4. If intentional, verify idempotency or subclass the filter so classes differ.

Example fix

// before: duplicate
http.addFilter(new UsernamePasswordAuthenticationFilter());
http.formLogin(Customizer.withDefaults());
// after: rely on DSL registration
http.formLogin(Customizer.withDefaults());
Defensive patterns

Strategy: validation

Validate before calling

// detect duplicate filter classes before enabling the chain
Set<Class<?>> seen = new HashSet<>();
for (Filter f : filters) {
    if (!seen.add(f.getClass())) {
        throw new IllegalStateException("Duplicate filter: " + f.getClass().getName());
    }
}

Prevention

When it happens

Trigger: Calling validate() on a FilterChainProxy whose security filter list contains two instances assignable to the same filter class, e.g. manually adding a filter that the namespace/DSL already registers, or declaring the same filter bean twice.

Common situations: Adding a custom or stock filter (e.g. UsernamePasswordAuthenticationFilter, CsrfFilter) via addFilterBefore/After when it is already in the chain; copying namespace config from XML to Java config and double-registering; multiple http blocks each adding the same filter.

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/ff2baa3b8373f298. Report an issue: GitHub.