{"record":{"id":"5331a6eb5f2a0b69","repo":"spring-projects/spring-security","slug":"spring-security-and-spring-mvc-must-use-the-same-p","errorCode":null,"errorMessage":"Spring Security and Spring MVC must use the same path pattern parser. To have Spring Security use Spring MVC's [{mvcParser}] simply publish this bean [{thisBean}] using its default constructor","messagePattern":"Spring Security and Spring MVC must use the same path pattern parser\\. To have Spring Security use Spring MVC's \\[(.+?)\\] simply publish this bean \\[(.+?)\\] using its default constructor","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"config/src/main/java/org/springframework/security/config/web/PathPatternRequestMatcherBuilderFactoryBean.java","lineNumber":89,"sourceCode":"\t * Please call the default constructor instead.\n\t * @param parser the {@link PathPatternParser} to use\n\t */\n\tpublic PathPatternRequestMatcherBuilderFactoryBean(PathPatternParser parser) {\n\t\tthis.parser = parser;\n\t}\n\n\t@Override\n\tpublic PathPatternRequestMatcher.Builder getObject() throws Exception {\n\t\tif (!this.context.containsBean(MVC_PATTERN_PARSER_BEAN_NAME)) {\n\t\t\tPathPatternParser parser = (this.parser != null) ? this.parser : PathPatternParser.defaultInstance;\n\t\t\treturn withPathPatternParser(parser);\n\t\t}\n\t\tPathPatternParser mvc = this.context.getBean(MVC_PATTERN_PARSER_BEAN_NAME, PathPatternParser.class);\n\t\tPathPatternParser parser = (this.parser != null) ? this.parser : mvc;\n\t\tif (mvc.equals(parser)) {\n\t\t\treturn withPathPatternParser(parser);\n\t\t}\n\t\tthrow new IllegalArgumentException(\"Spring Security and Spring MVC must use the same path pattern parser. \"\n\t\t\t\t+ \"To have Spring Security use Spring MVC's [\" + describe(mvc, MVC_PATTERN_PARSER_BEAN_NAME)\n\t\t\t\t+ \"] simply publish this bean [\" + describe(this, this.beanName) + \"] using its default constructor\");\n\t}\n\n\tprivate PathPatternRequestMatcher.Builder withPathPatternParser(PathPatternParser parser) {\n\t\tif (this.basePath == null) {\n\t\t\treturn PathPatternRequestMatcher.withPathPatternParser(parser);\n\t\t}\n\t\telse {\n\t\t\treturn PathPatternRequestMatcher.withPathPatternParser(parser).basePath(this.basePath);\n\t\t}\n\t}\n\n\t@Override\n\tpublic Class<?> getObjectType() {\n\t\treturn PathPatternRequestMatcher.Builder.class;\n\t}\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/config/src/main/java/org/springframework/security/config/web/PathPatternRequestMatcherBuilderFactoryBean.java#L71-L107","documentation":"PathPatternRequestMatcherBuilderFactoryBean aligns Spring Security's request-matching with Spring MVC's PathPatternParser. If the effective parser (custom injected parser or default) differs from the one Spring MVC uses in the context, getObject() throws IllegalArgumentException because security and MVC would interpret URL paths differently.","triggerScenarios":"Publishing PathPatternRequestMatcher.Builder with a non-default constructor/parser (e.g. withPathPatternParser() with a different parser instance) while a Spring MVC PathPatternParser bean exists and they are not equal.","commonSituations":"Customizing the parser via a custom bean definition after upgrading to Spring Security 7; mixing AntPathMatcher-based settings with MVC's pathpattern matching; bootstrapping the builder with a constructor argument in a MVC app.","solutions":["Publish PathPatternRequestMatcher.Builder using its default constructor so it adopts Spring MVC's parser","Change the custom parser so it equals the MVC parser instance/config","If MVC's parser must differ, adjust MVC pathmatch configuration so both sides match"],"exampleFix":"// before\n@Bean\nPathPatternRequestMatcher.Builder securityMatcherBuilder() {\n  return new PathPatternRequestMatcher.Builder(PathPatternParser.defaultInstance);\n}\n\n// after\n@Bean\nPathPatternRequestMatcher.Builder securityMatcherBuilder() {\n  return new PathPatternRequestMatcher.Builder(); // uses Spring MVC's parser\n}","handlingStrategy":"validation","validationCode":"PathPatternParser mvc = context.getBean(\"webMvcPathPatternParser\", PathPatternParser.class);\nPathPatternParser securityParser = /* parser you configured */;\nif (!mvc.equals(securityParser)) {\n  throw new IllegalStateException(\"Security and MVC path parsers differ; use the default constructor\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use the PathPatternRequestMatcher.Builder default constructor in MVC apps","Avoid custom PathPatternParser instances on the security side unless MVC uses the same one","Keep spring.mvc.pathmatch.matching-strategy consistent with security matching"],"tags":["spring-security","spring-mvc","path-matching","configuration-conflict"],"backgroundTag":"conflicting-config-options","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}