Trying to spin up the custom agent desktop inside the BYOC Edge environment, but the initialization sequence keeps bombing out. The genesyscloud SDK library walks through the bootstrap phase step by step, and it’ll attempt to open the WebSocket channel to wss://edge-relay.us-west-2.byc.genesiscloud.com. The request hits the load balancer. The handshake completes. Then the connection drops instantly.
Genesys Cloud Edge build 24.1.0-edge
BYOC infrastructure on Azure westus2
Client App SDK version 2.2.1
Manifest validation passes locally with gii validate
genesyscloud SDK library processes the init call and pushes the configuration object to the internal state machine. The code executes clientApp.init({ ... }). The SDK resolves the Edge endpoint from the discovery document. Network traces show the Connection: Upgrade header is present. The Edge proxy returns 101 Switching Protocols. Everything looks green for three seconds.
Then the console spits out the error.
WebSocket connection to 'wss://edge-relay...' failed: (1006) Abnormal closure
The buffer flushes. Doing jack all. The event loop catches the exception. The desktop UI stays blank. WAF rules disabled on Edge gateway. No change. The SDK retries three times. Each retry fails with the same code.
Checking the Edge logs shows the connection is accepted by the relay handler. The relay handler passes the frame to the application gateway. The gateway drops the frame because the X-Genesys-Edge-Token isn’t being forwarded correctly by the SDK transport layer. The SDK assumes the token is embedded in the query string. It’s not. The transport layer uses the header. The Edge config expects the header.
genesyscloud SDK library constructs the transport options using the createWebSocketTransport factory. The factory reads the baseUrl from the config. It doesn’t inject the token into the headers for the BYOC path. It works fine on standard public cloud. The BYOC Edge relay requires the token in the header for the WebSocket upgrade. The SDK doesn’t do that.
Manual patch of the WebSocket constructor gets past the drop. The connection stays open. Messages flow. Screen pops trigger. But this is a hack. The SDK version 2.2.1 doesn’t expose a hook for custom headers on the Edge transport.
Looking for a configuration option to pass the header without monkey patching the transport factory. Or is this a known gap in the BYOC Edge support for the client app SDK?
// Current transport behavior
const transport = clientApp.createTransport({
type: 'websocket',
url: config.edgeRelayUrl
});
// Missing header injection here
The relay drops the connection every time the SDK tries to send the keep-alive ping. The ping fails. The relay kills the session.
The 1006 drop on BYOC Edge usually means the relay accepted the TLS handshake but then dropped the connection because the genesys-cloud-tenant header isn’t attached to the WebSocket upgrade request. The standard SDK strips it out when it resolves the relay endpoint. You’ll need to force the header through the client config and point it at the correct BYOC API host so the WebSocket derivation works.
Drop that into your startup module. The relay will hold the connection once it sees the tenant context in the upgrade headers. If it still drops, check CloudWatch for the genesys.edge.relay log group. You’ll see a 401 Unauthorized or missing tenant context right before the close frame. Sometimes the JWT scope is also the culprit. Make sure webchat:read and interaction:read are actually attached to the token you’re passing. The SDK doesn’t validate scopes before opening the socket.
You can verify the token scope by hitting /api/v2/authorization/userinfo before initializing the socket. If it returns 403, the relay will drop it immediately. Run a quick curl -v against the relay endpoint with the same headers to verify the handshake sticks. If the relay responds with 101 Switching Protocols, the SDK config is your only remaining variable.
The header fix above handles standard web clients, but the SDK relay resolver often strips metadata when it detects a BYOC endpoint mismatch. A cleaner path is to force the tenant context into the WebSocket config object before the upgrade request fires. This mirrors how strict slot filling rules work in Dialog Engine flows. Runtime defaults won’t fill the missing values. The config object requires the exact parameter upfront, just like a bot flow JSON config needs explicit intent routing paths defined before deployment.
The relay drops the connection if the initial auth payload doesn’t match the edge node’s routing table. That’s the same behavior seen when a bot flow JSON config references an unverified NLU entity. The validation layer rejects the whole request. Tenant ID casing needs to match exactly. Miss one character and the handshake drops instantly. Community posts from last month show this exact pattern when moving from standard US nodes to regional BYOC relays.
[screenshot: ws_config_payload.png]
SDK version mismatches break the protocol negotiation. The 1006 error usually clears once the payload matches.
Problem
The platform API docs don’t explicitly cover the header stripping on BYOC endpoints, but the SDK drops the connection when the tenant context goes missing.