{"record":{"id":"65584133a365dd1d","repo":"spring-projects/spring-security","slug":"a-reactivesessionregistry-is-needed-for-concurrent","errorCode":null,"errorMessage":"A ReactiveSessionRegistry is needed for concurrent session management","messagePattern":"A ReactiveSessionRegistry is needed for concurrent session management","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java","lineNumber":1582,"sourceCode":"\n\t\tprivate void configureSuccessHandlerOnAuthenticationFilters() {\n\t\t\tif (ServerHttpSecurity.this.formLogin != null) {\n\t\t\t\tServerHttpSecurity.this.formLogin.defaultSuccessHandlers.add(0, this.authenticationSuccessHandler);\n\t\t\t}\n\t\t\tif (ServerHttpSecurity.this.oauth2Login != null) {\n\t\t\t\tServerHttpSecurity.this.oauth2Login.defaultSuccessHandlers.add(0, this.authenticationSuccessHandler);\n\t\t\t}\n\t\t\tif (ServerHttpSecurity.this.httpBasic != null) {\n\t\t\t\tServerHttpSecurity.this.httpBasic.defaultSuccessHandlers.add(0, this.authenticationSuccessHandler);\n\t\t\t}\n\t\t}\n\n\t\tprivate ReactiveSessionRegistry getSessionRegistry() {\n\t\t\tif (this.sessionRegistry == null) {\n\t\t\t\tthis.sessionRegistry = getBeanOrNull(ReactiveSessionRegistry.class);\n\t\t\t}\n\t\t\tif (this.sessionRegistry == null) {\n\t\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\t\"A ReactiveSessionRegistry is needed for concurrent session management\");\n\t\t\t}\n\t\t\treturn this.sessionRegistry;\n\t\t}\n\n\t\t/**\n\t\t * Configures how many sessions are allowed for a given user.\n\t\t */\n\t\tpublic class ConcurrentSessionsSpec {\n\n\t\t\t/**\n\t\t\t * Sets the {@link ReactiveSessionRegistry} to use.\n\t\t\t * @param reactiveSessionRegistry the {@link ReactiveSessionRegistry} to use\n\t\t\t * @return the {@link ConcurrentSessionsSpec} to continue customizing\n\t\t\t */\n\t\t\tpublic ConcurrentSessionsSpec sessionRegistry(ReactiveSessionRegistry reactiveSessionRegistry) {\n\t\t\t\tSessionManagementSpec.this.sessionRegistry = reactiveSessionRegistry;\n\t\t\t\treturn this;","sourceCodeStart":1564,"sourceCodeEnd":1600,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java#L1564-L1600","documentation":"Concurrent session control in reactive Spring Security requires a ReactiveSessionRegistry to track sessions per principal. If none is configured via DSL and no ReactiveSessionRegistry bean exists in the context, getSessionRegistry() throws this IllegalStateException.","triggerScenarios":"Configuring maximumSessions in reactive ServerHttpSecurity without defining a ReactiveSessionRegistry bean and without supplying one via sessionRegistry() in the DSL.","commonSituations":"Enabling concurrent session limits in a WebFlux app that never registered the reactive session registry; removing the InMemoryReactiveSessionRegistry bean during refactoring; test contexts missing the bean.","solutions":["Publish a ReactiveSessionRegistry bean (e.g. InMemoryReactiveSessionRegistry) in the application context","Set it explicitly in the DSL: .sessionManagement(s -> s.maximumSessions(...).sessionRegistry(registry))","If concurrency control is unnecessary, remove the maximumSessions configuration"],"exampleFix":"// before\n@Bean\nSecurityWebFilterChain filterChain(ServerHttpSecurity http) {\n  return http.sessionManagement(s -> s.maximumSessions(SessionLimit.of(1))).build();\n}\n\n// after\n@Bean\nReactiveSessionRegistry reactiveSessionRegistry() { return new InMemoryReactiveSessionRegistry(); }\n@Bean\nSecurityWebFilterChain filterChain(ServerHttpSecurity http) {\n  return http.sessionManagement(s -> s.maximumSessions(SessionLimit.of(1))).build();\n}","handlingStrategy":"validation","validationCode":"if (context.getBeanNamesForType(ReactiveSessionRegistry.class).length == 0) {\n  throw new IllegalStateException(\"Define a ReactiveSessionRegistry bean for concurrent session control\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always register an InMemoryReactiveSessionRegistry bean when using maximumSessions","Pass the registry explicitly through the sessionRegistry() DSL method","Add a startup smoke test that builds the filter chain"],"tags":["reactive","session","spring-security","missing-bean"],"backgroundTag":"missing-required-config","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}