After upgrading our CMS from 4.4.3 to 4.5.0 (custom/manual installation, not the Docker image), our players’ XMR WebSocket connections started closing almost immediately after connecting, repeatedly. This affects any client type – confirmed identically with both a third-party Linux player (arexibo) and the official Windows player.
On the XMR relay’s own log:
[2026-08-10 14:30:55] xmr.ERROR: onMessage: Invalid key [] []
repeating on the same cadence as each player’s reconnect attempts, regardless of which client connects.
Traced this to src/Controller/Server.php’s onMessage():
php
if (!$this->queue->authKey($key)) {
throw new \InvalidArgumentException('Invalid key');
}
Queue::authKey() only returns true if a matching key was previously registered via Queue::addKey($instance, $key), which (per src/Controller/Api.php) only happens when the CMS itself POSTs {"type":"keys","id":...,"key":...} to the relay’s private API address.
Verified before reporting, to rule out a configuration issue on our end:
- XMR Private Address in CMS settings (
http://localhost:8081) matches the relay’s ownconfig.json("api": "0.0.0.0:8081"). - Confirmed the endpoint is reachable and functioning correctly from the CMS server itself:
curl -X POST http://localhost:8081 -d '{"type":"stats"}'
→ 200 OK, valid JSON stats response
- This rules out a network/address misconfiguration; the CMS should be able to reach the relay’s API without issue.
Given connectivity is confirmed working, it appears the CMS-side code that’s supposed to call this "keys" endpoint (to register a valid key for a display’s channel) is either never triggered, or not wired up for a standard single-instance CMS deployment – authKey() always returns false regardless of what key any player sends, for any client type.
Question: is there a CMS-side code path that’s supposed to call the relay’s "keys" API endpoint proactively (e.g. during RegisterDisplay, on a schedule, or on CMS startup) that might be missing or not firing for a standard single-instance deployment? Given Relay/isRelay()/isRelayOld() in index.php suggest this key mechanism may be designed primarily for a multi-instance relay scenario, we suspect this registration call may simply never happen in a standard setup.
(Side note, possibly unrelated: our XMR Public Address is currently set to ws://<ip>:9505, but port 9505 in config.json is configured for ZMQ ("zmq": ["tcp://*:9505"]), not WebSocket – this looks like it should be tcp:// for the legacy ZMQ fallback address, not ws://. Flagging this in case it’s relevant, though we don’t believe it’s the cause of the “Invalid key” issue specifically.)
Happy to provide more logs/detail if useful.