{"record":{"id":"432ccd2d548add8f","repo":"spring-projects/spring-security","slug":"the-filter-class-filter-getclass-getname-doe","errorCode":null,"errorMessage":"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.","messagePattern":"The Filter class (.+?) does not have a registered order and cannot be added without a specified order\\. Consider using addFilterBefore or addFilterAfter instead\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java","lineNumber":1846,"sourceCode":"\t}\n\n\tprivate HttpSecurity addFilterAtOffsetOf(Filter filter, int offset, Class<? extends Filter> registeredFilter) {\n\t\tInteger registeredFilterOrder = this.filterOrders.getOrder(registeredFilter);\n\t\tif (registeredFilterOrder == null) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"The Filter class \" + registeredFilter.getName() + \" does not have a registered order\");\n\t\t}\n\t\tint order = registeredFilterOrder + offset;\n\t\tthis.filters.add(new OrderedFilter(filter, order));\n\t\tthis.filterOrders.put(filter.getClass(), order);\n\t\treturn this;\n\t}\n\n\t@Override\n\tpublic HttpSecurity addFilter(Filter filter) {\n\t\tInteger order = this.filterOrders.getOrder(filter.getClass());\n\t\tif (order == null) {\n\t\t\tthrow new IllegalArgumentException(\"The Filter class \" + filter.getClass().getName()\n\t\t\t\t\t+ \" does not have a registered order and cannot be added without a specified order. Consider using addFilterBefore or addFilterAfter instead.\");\n\t\t}\n\t\tthis.filters.add(new OrderedFilter(filter, order));\n\t\treturn this;\n\t}\n\n\t/**\n\t * Adds the Filter at the location of the specified Filter class. For example, if you\n\t * want the filter CustomFilter to be registered in the same position as\n\t * {@link UsernamePasswordAuthenticationFilter}, you can invoke:\n\t *\n\t * <pre>\n\t * addFilterAt(new CustomFilter(), UsernamePasswordAuthenticationFilter.class)\n\t * </pre>\n\t *\n\t * Registration of multiple Filters in the same location means their ordering is not\n\t * deterministic. More concretely, registering multiple Filters in the same location\n\t * does not override existing Filters. Instead, do not register Filters you do not","sourceCodeStart":1828,"sourceCodeEnd":1864,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java#L1828-L1864","documentation":"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.","triggerScenarios":"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.","commonSituations":"Porting XML <custom-filter> configs to Java config; developers assuming addFilter works like addFilterBefore; custom filters extending OncePerRequestFilter directly.","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"],"exampleFix":"// before\nhttp.addFilter(new MyTokenFilter());\n// after\nhttp.addFilterBefore(new MyTokenFilter(), UsernamePasswordAuthenticationFilter.class);","handlingStrategy":"fallback","validationCode":"Integer order = /* filter order registry lookup */;\nif (order == null) {\n    // use addFilterBefore/addFilterAfter instead of addFilter\n}","typeGuard":null,"tryCatchPattern":"try {\n    http.addFilter(filter);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"does not have a registered order\")) {\n        http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);\n    } else throw e;\n}","preventionTips":["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"],"tags":["spring-security","filter-chain","httpsecurity","configuration"],"backgroundTag":"invalid-argument-value","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"}