All users force-logged out at once for a few minutes, then it self-recovers
Environment
- Vaadin Flow 24.10 (
productionMode: true) - Spring Boot 3.5.3, Spring Security
- JDK 21
- Packaged in Docker, single container instance, behind an nginx-family reverse proxy
- Multi-datasource: 1 MySQL (core / app data incl. users & permissions) + several SQL Server read pools, all HikariCP
- Server-side sessions (currently verifying whether Spring Session is in play or plain in-memory Tomcat sessions)
Symptom
Every so often, with no fixed schedule, every logged-in user is bounced to the login page at the same moment.
- Lasts ~1 to several minutes
- Recovers on its own — no restart, no redeploy
- Logging back in doesn’t help: a fresh session gets bounced again on the next navigation click
- Container stays up. No OOM, no crash
That last point is the interesting one. A brand-new session shouldn’t be affected if this were session expiry.
The likely mechanism
We have a global navigation guard — a BeforeEnterListener registered via VaadinServiceInitListener — that queries the DB for the user’s permissions on every navigation event. If it fails or throws, it reroutes to login.
So any DB slowness → permission lookup fails → reroute to login → indistinguishable from mass session expiry. And it explains the re-login behaviour, since the check is per-navigation, not per-session.
Already addressed / ruled out
- Hikari was tuned badly:
connection-timeout: 60000(requests block a full minute instead of failing fast),minimum-idle: 2vsmaximum-pool-size: 50, shortmax-lifetime, nosocketTimeout. All being fixed. - Permission lookup is uncached — adding Caffeine
@Cacheableregardless of root cause. - DEBUG on
com.zaxxer.hikari+org.apache.catalina.session, Tomcat access log with%D %S, and ajcmdthread dump script (actuator on the same connector is useless during thread exhaustion). - Frequent Atmosphere
IllegalStateException: request object has been recycledwarnings — believed benign, but they seem to cluster around the logout events.
Questions
- Has anyone seen this exact shape — simultaneous, minutes-long, self-recovering, random timing? What was it?
- Is a DB-querying
BeforeEnterListenera known antipattern? It turns every latency spike into an auth-looking failure. Is there a better place for permission checks in Flow, or is the answer just “cache it and never touch the DB in a guard”? - Session lock: Flow serializes requests per session. If a navigation request holds that lock while blocked on a slow DB call, does everything else for that user queue behind it? Any recommended guard against blocking I/O under the session lock?
- Are those Atmosphere recycled-request warnings truly harmless, or can they signal push connections dying in a way that correlates with session loss?
- Is
addSessionDestroyListenerthe right way to definitively separate “session actually died” from “guard rejected navigation”? Anything else in Flow that logs why a user was redirected?
Happy to share thread dumps, pool metrics, or config once I capture a clean incident window. Pointers especially welcome from anyone running Flow with a permission check on the navigation path.