Hello

Here is a Playbook we created to address the Orphan session issue along with how to set up systemd and or Cron with script to keep them cleaned up.

Hope this helps, we also have a MFA fail / success detection script as well that runs in the background.


*Thank You*
Sean Hulbert


On 5/3/2026 5:01 AM, Nick Couchman wrote:
‪On Sun, Apr 26, 2026 at 11:58 AM ‫נחום בר כהן‬‎<[email protected]> wrote:‬
Hi all,
I’m running Guacamole 1.6.0 (Docker, MySQL + LDAP + TOTP, behind a Cloudflare 
Zero Trust tunnel) and hit a consistently reproducible issue where active 
sessions are never cleaned up after disconnect.
Reproduction steps

Initiate a connection by a user
Disconnect
Navigate to active connections view
See the connection still present there, even after long time

Symptoms

Active Sessions UI shows the session permanently until guacamole-app restarts. 
The sessions accumulate over time
Kill session makes the session disappear in the UI, but a page refresh shows 
the session again
guacd has no active children — the ghost is purely in-memory

Log

Exception in thread "Thread-4" java.lang.IllegalStateException:
     Message will not be sent because the WebSocket session has been closed
     at 
org.apache.guacamole.websocket.GuacamoleWebSocketTunnelEndpoint.sendInstruction(...:152)
     at 
org.apache.guacamole.websocket.GuacamoleWebSocketTunnelEndpoint$2.run(...:253)

Root cause (identified via bytecode inspection using Claude)
GuacamoleWebSocketTunnelEndpoint$2.run() — the writer thread — catches 
GuacamoleException and its subclasses, but not RuntimeException. When the 
browser closes the WebSocket mid-send (race condition on disconnect), Tomcat 
throws IllegalStateException: Message will not be sent because the WebSocket 
session has been closed. The thread dies unhandled. The finally block calls 
tunnel.close() but does not call session.close(), so Tomcat never fires 
@OnClose. Without @OnClose, ConnectionCleanupTask never runs and the 
ActiveConnectionRecord is never removed from the in-memory tracker.
Suggested fix (by Claude)
Add session.close() to the writer thread’s finally block, and catch 
RuntimeException alongside GuacamoleException:

} finally {
     try { session.close(); } catch (Exception e) { /* ignore */ }
     try { tunnel.close(); } catch (GuacamoleException e) { ... }
}

Is this a known issue? I'll be glad to open a JIRA if it’s confirmed. I can 
also share more logs if required.

I do not believe this is a known issue, and I am not seeing this issue
in my environment. I'm not operating behind CloudFlare Zero Trust
tunnel, though I do tend to operate behind Zscaler's equivalent
version (Zscaler Private Access), and my session list seems to be
reflective of what sessions are actually running.

You're welcome to open a Jira issue and a pull request - it does seem
like it could be worth manually closing the session and tunnel in that
finally block.

-Nick

---------------------------------------------------------------------
To unsubscribe, e-mail:[email protected]
For additional commands, e-mail:[email protected]

Attachment: guacd_cleanup_Orphan_sessions.docx
Description: MS-Word 2007 document

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to