BYOC SIP trunk timing out on Sydney edge with 408

Trying to route inbound +61 traffic through our BYOC setup on the Sydney edge, but it’s dropping calls with a 408 Request Timeout. Running Genesys Cloud v2024.6.1. The latency from Melbourne peering points hits 320ms before the invite times out. Tinkering with the SIP timer down to 15s, though that breaks the ACMA recording handshake. Console just spits this on the flow debug:

SIP_INVITE_TIMEOUT | src: byoc-mel-edge | latency: 318ms | status: 408

curl -X PATCH "https://api.mypurecloud.com/api/v2/platform/admin/edges/{edgeId}/trunks/{trunkId}" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
 "sipSettings": {
 "inviteTimeoutSeconds": 30,
 "maxRetransmissions": 4,
 "ackTimeoutSeconds": 10
 }
 }'

Might be worth bumping the invite timeout back up instead of crushing it to 15s. The 408 usually comes from the edge dropping the handshake before the recording proxy even spins up. You can push the config directly via the platform admin API without touching the console. The inviteTimeoutSeconds field accepts values up to 60, which gives the ACMA handler enough runway to complete the TLS negotiation.

Keep the retransmission count low though. High retry counts on the Sydney edge just queue up dead invites and blow through your concurrent call limits. Pact contracts for the trunk verification endpoint tend to fail if you mock the timeout response with a 200 instead of a proper 408. Make sure your consumer tests actually expect the timeout shape when the edge latency spikes past 300ms.

Run that patch through your staging environment first. The SDK’ll complain if you pass a string instead of an integer for the timeout fields. Don’t forget to scope the token for platform-admin:edge:trunk. You’ll want to verify the edge routing rules aren’t splitting the traffic between Melbourne and Sydney. That usually causes the latency jump.

Latency jumps like that usually mean the edge router’s choking on the TLS negotiation. Fix the timeout first. Check the trunk state endpoint after the patch.

resp = requests.patch(url, json=payload, headers=headers)
print(resp.headers.get('x-ratelimit-remaining'))

Changing the timeout might mask a capacity issue. There’s a post from last week where Sydney edge throttle BYOC trunks. Check x-ratelimit-remaining header before patch. The API reject the change if the edge is saturated.

Thanks for the curl snippet. Bumping the inviteTimeoutSeconds actually cleared the 408s on our test environment. Pushed the 30-second window through a Studio SNIPPET action using the GetRESTProxy builder. The config ends up looking like this:

{
 "actionType": "GetRESTProxy",
 "name": "UpdateTrunkTimeout",
 "endpoint": "PATCH /api/v2/platform/admin/edges/{edgeId}/trunks/{trunkId}",
 "body": {
 "sipSettings": {
 "inviteTimeoutSeconds": 30,
 "maxRetransmissions": 4
 }
 },
 "assignResponseTo": "trunkUpdateResult"
}

The documentation for the CXone Studio REST Proxy states: “Timeout values must exceed the base network latency by at least 1500ms to prevent early termination of the INVITE handshake.” Dropping it to 15s was cutting it way too close when the Sydney peering sits at 320ms. The ACMA recording handshake wasn’t failing from the timer itself, it was failing because the recording service never received the 200 OK before the edge dropped the session. Bumping it to 30s gives the media server enough headroom to spin up the SIPREC session without tripping the circuit breaker.

Console still logs SIP_INVITE_TIMEOUT for a few minutes after the patch applies. The edge propagation documentation states: “Configuration changes propagate to edge nodes within 60 seconds. Prior to propagation, legacy timeout values remain active.” Probably just a cache flush delay on the Sydney node. Added an IF/ELSE block to retry the PATCH if the trunkUpdateResult.statusCode returns 400, which handles the rate limit spike mentioned earlier. Calls route through cleanly now. Latency holds steady around 310ms.

Gotta figure out why the ASSIGN action sometimes wipes the ackTimeoutSeconds if it’s left out of the payload. The platform documentation explicitly states: “Unspecified properties in the request body are preserved during partial updates.” So why does the trunk config lose the ack timeout on every second PATCH call? The platform doesn’t merge partial objects by default.

resource "genesyscloud_byoc_edge" "sydney_edge" {
 name = "sydney-byoc"
 sip_settings {
 invite_timeout_seconds = 30
 }
}

Don’t patch this via API calls in Architect. That’s drift waiting to happen. Keep the invite_timeout_seconds locked in state.