Found part of the issue. To secure the services I use OpenVPN, even for SSH. For this example the "public hostname" is example.com. When you connect to the OpenVPN service example.com you can now also reach example.com through the secure VPN with IP 10.8.0.1. The broker only listens on 10.8.0.1, so this means you need both a device holding the OpenVPN keys and username+password in the broker to log in. This way external, untrusted devices cannot try to log in at all. SSH daemon requires public keys, password auth is disabled. In session profiles inifile, previously the value was host=10.8.0.1. This way the SSH traffic gets tunnelled through the VPN too. Now that this is changed to host=example.com, I can see status "(suspended)" or "(running)" in x2goclient, depending on the server state. X2Go always uses the system's real $HOST to determine the session hostname. So even if inifile host=10.8.0.1 x2golistsessions will lists it as: 12345|foobar-50-....|50|example.com|... Even though suspended/running status now works clicking on the suspended session in x2goclient still starts up a new session. The broker log: > base_broker.X2GoBroker.select_session(): no X2Go Server could be contacted, > session startup will fail, tried these hosts: ['example.com'] The fix was to use the host syntax documented in load balancing mode: host=example.com (10.8.0.1) With this change everything works perfectly. I think the documentation, perhaps in the inifile itself, should add some IMPORTANT note regarding this. If the host field is not properly configured many things don't work properly. tl;dr The host name MUST match whatever is listed in x2golistsessions and the host IP/target MUST match whatever the broker is bound to.