Problem Statement
When using Redis session manager in a dotCMS cluster with 2 nodes, sessions can expire unexpectedly even while they are actively used on another node.
The root cause if that each dotCMS node independently runs its local Tomcat session expiration logic (based on the last access time for the local Tomcat session), and when a node decides a session is idle, it explicitly deletes the session from Tomcat and Redis. This happens even if it the session is actively used on the other node and Redis TTL has been refreshed correctly on the other node.
As a result, a single node with no recent traffic for a given session can invalidate the session cluster-wide, causing users to be logged out unexpectedly.
Steps to Reproduce
- Setup a dotCMS cluster with 2 nodes configured to use the Redis session manager and pointing to the same Redis instance. You can use these environment properties for your dotCMS nodes:
TOMCAT_REDIS_SESSION_ENABLED="true"
TOMCAT_REDIS_SESSION_HOST="redis"
TOMCAT_REDIS_SESSION_PORT="6379"
TOMCAT_REDIS_SESSION_PASSWORD="<redis-password>"
TOMCAT_REDIS_SESSION_SSL_ENABLED="true"
TOMCAT_REDIS_SESSION_PERSISTENT_POLICIES="DEFAULT"
- Set the user session timeout to 5 minutes for the Redis session manager (or use just a few minutes for the timeout, so you don't have to wait a lot of time for session expiration)
TOMCAT_REDIS_USER_SESSION_TIMEOUT="300"
- Disable the Remember Me cookie so the user is not automatically authenticated when the session expired:
DOT_SET_JWT_SESSION_COOKIE="false"
- Setup a proxy/load balancer in front of your dotCMS cluster, so you can forward request to one node or the other.
- Start the dotCMS cluster nodes and the proxy to forward requests from your browser to the cluster nodes.
- Login into dotCMS and create a session, by forwarding the request to the cluster first node (node A).
- Now forward next request to node B only for a period longer than 5 minutes (or the session timeout configured in the cluster). Redis TTL continues to be refreshed by node B requests, so the session shouldn't expire because there are no 5 minutes of inactivity.
- Do no forward requests to node A during this time.
- Wait until node A local session expiration thread runs.
- Node A determines the session is idle and deletes the session from Redis.
- Forward a new request to node A using the same session ID
- You are asked to login and start a new session because the session already expired, even if the user wasn't inactive for 5 minutes.
Acceptance Criteria
- A session that is actively accessed on any cluster node should remain valid
- Tomcat shouldn't delete a session from Redis solely because it appears idle from its local perspective.
- Redis session manager should govern session expiration according to the cluster wide TTL, not by node local expiration logic.
dotCMS Version
Evergreen version 26.01.29-01
Severity
Medium - Some functionality impacted
Links
Freshdesk ticket 34590
Problem Statement
When using Redis session manager in a dotCMS cluster with 2 nodes, sessions can expire unexpectedly even while they are actively used on another node.
The root cause if that each dotCMS node independently runs its local Tomcat session expiration logic (based on the last access time for the local Tomcat session), and when a node decides a session is idle, it explicitly deletes the session from Tomcat and Redis. This happens even if it the session is actively used on the other node and Redis TTL has been refreshed correctly on the other node.
As a result, a single node with no recent traffic for a given session can invalidate the session cluster-wide, causing users to be logged out unexpectedly.
Steps to Reproduce
Acceptance Criteria
dotCMS Version
Evergreen version 26.01.29-01
Severity
Medium - Some functionality impacted
Links
Freshdesk ticket 34590