WebRTC ICE candidates failing to traverse NAT behind ServiceNow Virtual Agent iframe

The browser console logs show: RTCIceConnectionState: failed followed immediately by WebRTC negotiation failed: ICE connection failed. This is occurring exclusively when the Genesys Cloud WebRTC softphone is embedded within a ServiceNow Virtual Agent iframe using the latest Genesys Cloud Engagement SDK (v2.4.1). Direct access to the Genesys Cloud UX works flawlessly with no STUN/TURN issues, confirming the network path is valid. However, once instantiated within the ServiceNow portal container, the ICE candidates generated appear to be blocked by the corporate firewall’s strict NAT traversal policies, likely due to the iframe’s cross-origin restrictions interfering with the UDP hole punching mechanism.

The ServiceNow side is configured with the correct CORS headers, and the Genesys Cloud tenant has the necessary WebRTC endpoints enabled. I have verified that the ServiceNow instance is not stripping any headers from the WebSocket handshake. The issue seems to stem from the interaction between the ServiceNow iframe sandboxing and the WebRTC peer connection establishment. Has anyone successfully integrated the Genesys Cloud WebRTC client within a ServiceNow Virtual Agent widget without encountering this ICE failure? I need to determine if this requires a specific TURN server configuration in Genesys Cloud to bypass the NAT restrictions imposed by the ServiceNow container, or if there is a known limitation with the Engagement SDK when running in an iframe context.

This is typically caused by the iframe blocking the WebSocket connection required for ICE candidate gathering.
The ServiceNow sandbox likely restricts the wss:// protocol. Check the CSP headers in the parent frame. JMeter tests show that blocking the signaling channel breaks the media path immediately. You need to add the Genesys WebSocket domain to the allowed origins in ServiceNow.

It depends, but generally…

The browser console logs show: RTCIceConnectionState: failed followed immediately by WebRTC negotiation failed: ICE connection failed. This is occurring exclusively when the Genesys Cloud WebRTC softphone is embedded within a ServiceNow Virtual Agent iframe…

The previous point about CSP headers is valid, but the issue often lies deeper in the STUN/TURN server reachability from within the sandboxed context. When running inside an iframe, the browser may enforce stricter network isolation, preventing direct UDP traffic to standard STUN servers.

To resolve this, explicitly configure the WebRTC settings in your Genesys Cloud Engagement SDK initialization to use relay-only TURN servers. This forces traffic over TCP/HTTPS, bypassing NAT traversal issues that plague UDP in restricted environments.

const webrtcConfig = {
 iceServers: [
 { urls: ['turn:turn.genesis.com:443?transport=tcp'], username: 'user', credential: 'pass' }
 ],
 iceTransportPolicy: 'relay'
};

Verify your BYOC trunk configuration allows TCP-based media fallback. This ensures the signaling remains intact even if the direct ICE path is blocked by the ServiceNow container.