spring-projects/spring-security · error · IllegalStateException

A ReactiveSessionRegistry is needed for concurrent session m

Error message

A ReactiveSessionRegistry is needed for concurrent session management

What it means

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.

Source

Thrown at config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java:1582

		private void configureSuccessHandlerOnAuthenticationFilters() {
			if (ServerHttpSecurity.this.formLogin != null) {
				ServerHttpSecurity.this.formLogin.defaultSuccessHandlers.add(0, this.authenticationSuccessHandler);
			}
			if (ServerHttpSecurity.this.oauth2Login != null) {
				ServerHttpSecurity.this.oauth2Login.defaultSuccessHandlers.add(0, this.authenticationSuccessHandler);
			}
			if (ServerHttpSecurity.this.httpBasic != null) {
				ServerHttpSecurity.this.httpBasic.defaultSuccessHandlers.add(0, this.authenticationSuccessHandler);
			}
		}

		private ReactiveSessionRegistry getSessionRegistry() {
			if (this.sessionRegistry == null) {
				this.sessionRegistry = getBeanOrNull(ReactiveSessionRegistry.class);
			}
			if (this.sessionRegistry == null) {
				throw new IllegalStateException(
						"A ReactiveSessionRegistry is needed for concurrent session management");
			}
			return this.sessionRegistry;
		}

		/**
		 * Configures how many sessions are allowed for a given user.
		 */
		public class ConcurrentSessionsSpec {

			/**
			 * Sets the {@link ReactiveSessionRegistry} to use.
			 * @param reactiveSessionRegistry the {@link ReactiveSessionRegistry} to use
			 * @return the {@link ConcurrentSessionsSpec} to continue customizing
			 */
			public ConcurrentSessionsSpec sessionRegistry(ReactiveSessionRegistry reactiveSessionRegistry) {
				SessionManagementSpec.this.sessionRegistry = reactiveSessionRegistry;
				return this;

View on GitHub (pinned to 96852e8860)

Solutions

  1. Publish a ReactiveSessionRegistry bean (e.g. InMemoryReactiveSessionRegistry) in the application context
  2. Set it explicitly in the DSL: .sessionManagement(s -> s.maximumSessions(...).sessionRegistry(registry))
  3. If concurrency control is unnecessary, remove the maximumSessions configuration

Example fix

// before
@Bean
SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
  return http.sessionManagement(s -> s.maximumSessions(SessionLimit.of(1))).build();
}

// after
@Bean
ReactiveSessionRegistry reactiveSessionRegistry() { return new InMemoryReactiveSessionRegistry(); }
@Bean
SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
  return http.sessionManagement(s -> s.maximumSessions(SessionLimit.of(1))).build();
}
Defensive patterns

Strategy: validation

Validate before calling

if (context.getBeanNamesForType(ReactiveSessionRegistry.class).length == 0) {
  throw new IllegalStateException("Define a ReactiveSessionRegistry bean for concurrent session control");
}

Prevention

When it happens

Trigger: Configuring maximumSessions in reactive ServerHttpSecurity without defining a ReactiveSessionRegistry bean and without supplying one via sessionRegistry() in the DSL.

Common situations: 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.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/65584133a365dd1d. Report an issue: GitHub.