spring-projects/spring-security · error · IllegalArgumentException
The Filter class {filter.getClass().getName()} does not have
Error message
The Filter class {filter.getClass().getName()} does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead. What it means
HttpSecurity.addFilter expects the filter's class to already have a registered order (i.e. it is a known Spring Security filter). For arbitrary custom filters there is no order, so addFilter throws this IllegalArgumentException directing you to addFilterBefore/addFilterAfter instead.
Source
Thrown at config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java:1846
}
private HttpSecurity addFilterAtOffsetOf(Filter filter, int offset, Class<? extends Filter> registeredFilter) {
Integer registeredFilterOrder = this.filterOrders.getOrder(registeredFilter);
if (registeredFilterOrder == null) {
throw new IllegalArgumentException(
"The Filter class " + registeredFilter.getName() + " does not have a registered order");
}
int order = registeredFilterOrder + offset;
this.filters.add(new OrderedFilter(filter, order));
this.filterOrders.put(filter.getClass(), order);
return this;
}
@Override
public HttpSecurity addFilter(Filter filter) {
Integer order = this.filterOrders.getOrder(filter.getClass());
if (order == null) {
throw new IllegalArgumentException("The Filter class " + filter.getClass().getName()
+ " does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead.");
}
this.filters.add(new OrderedFilter(filter, order));
return this;
}
/**
* Adds the Filter at the location of the specified Filter class. For example, if you
* want the filter CustomFilter to be registered in the same position as
* {@link UsernamePasswordAuthenticationFilter}, you can invoke:
*
* <pre>
* addFilterAt(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)
* </pre>
*
* Registration of multiple Filters in the same location means their ordering is not
* deterministic. More concretely, registering multiple Filters in the same location
* does not override existing Filters. Instead, do not register Filters you do notView on GitHub (pinned to 96852e8860)
Solutions
- Replace addFilter with http.addFilterBefore(filter, SomeExistingSecurityFilter.class) or addFilterAfter
- Alternatively use addFilterAt(filter, ExistingSecurityFilter.class) to pin it to a known slot
- If the filter extends a built-in security filter, register the exact built-in class position and keep the subclass's effective order consistent
Example fix
// before http.addFilter(new MyTokenFilter()); // after http.addFilterBefore(new MyTokenFilter(), UsernamePasswordAuthenticationFilter.class);
Defensive patterns
Strategy: fallback
Validate before calling
Integer order = /* filter order registry lookup */;
if (order == null) {
// use addFilterBefore/addFilterAfter instead of addFilter
} Try / catch
try {
http.addFilter(filter);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("does not have a registered order")) {
http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
} else throw e;
} Prevention
- Default to addFilterBefore/addFilterAfter for all custom filters
- Reserve addFilter for genuine Spring Security filters with known comparator order
- Centralize filter registration in one security config method to keep anchor choices consistent
When it happens
Trigger: Calling http.addFilter(new MyCustomFilter()) where MyCustomFilter is not a Spring Security filter with a registered comparator order; adding a subclass whose concrete class is unknown to the filter order registry.
Common situations: Porting XML <custom-filter> configs to Java config; developers assuming addFilter works like addFilterBefore; custom filters extending OncePerRequestFilter directly.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- The Filter class {registeredFilter.getName()} does not have
- A filter chain that matches any request [{anyRequestFilterCh
- The FilterChainProxy contains two filter chains using the ma
- Possible error: Filters at position <i> and <j> are both ins
- Cannot apply {configurer} to already built object
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/432ccd2d548add8f.
Report an issue: GitHub.