Resolving SIP 487 Request Terminated Errors in CXone Outbound Dialers Caused by Premature CANCEL Requests from High-Latency Carrier Networks
What This Guide Covers
This guide details the architectural adjustments required to eliminate SIP 487 errors in NICE CXone outbound dialers when high-latency carrier networks trigger premature SIP CANCEL messages. You will configure dialer timeout thresholds, override SIP stack timers, and implement carrier-aware routing to align CXone signaling behavior with real-world network propagation delays.
Prerequisites, Roles & Licensing
- Licensing: CXone Outbound Dialer (Predictive, Progressive, or Power Dialing), CXone Telephony/Trunking tier, CXone Analytics (for call log correlation)
- Granular Permissions:
Telephony > Trunking > Trunks > Edit,Outbound > Campaigns > Edit,Analytics > Call Log > View,Administration > API Credentials > Manage - OAuth Scopes:
telephony:trunks:write,outbound:campaigns:write,analytics:reports:read,telephony:monitoring:read - External Dependencies: Carrier SIP trace access, network path RTT measurements, CXone SBC/trunk endpoint configuration, DNS resolution validation for SIP domains
The Implementation Deep-Dive
1. Diagnose Latency-Triggered CANCEL Behavior & Log Correlation
SIP 487 (Request Terminated) is not a carrier rejection code. It is a local termination event indicating that the User Agent Client (UAC) aborted a pending INVITE by sending a CANCEL request, or that an intermediary B2BUA terminated the transaction before receiving a final response. In CXone outbound architecture, the dialer engine acts as the UAC. When network latency exceeds the dialer’s initial response timeout, CXone generates a CANCEL before the carrier can return 100 Trying or 180 Ringing. The call log records this as a 487.
Begin by isolating 487 events and correlating them with actual network round-trip time (RTT). Query the CXone analytics API to extract calls terminated with 487 within the last twenty-four hours. Filter by trunk group and dialer campaign to establish a baseline.
GET /api/v2/analytics/details/query?body={
"reportSpec": {
"type": "call",
"query": {
"filter": {
"type": "AND",
"clauses": [
{
"type": "EQ",
"field": "callOutcome",
"value": "487"
},
{
"type": "EQ",
"field": "direction",
"value": "outbound"
}
]
},
"timeFilter": {
"type": "relative",
"value": "-24h"
},
"groupings": [
{"type": "field", "field": "trunkName"},
{"type": "field", "field": "campaignName"}
],
"metrics": [
{"type": "count", "field": "callId"},
{"type": "avg", "field": "callSetupTime"},
{"type": "max", "field": "networkLatencyMs"}
]
}
}
}
Execute this query and examine the networkLatencyMs metric. If the average latency exceeds 2500ms and correlates directly with 487 volume, the root cause is timeout mismatch, not carrier rejection. Capture raw SIP traces using CXone’s monitoring endpoint to verify that the CANCEL originates from the CXone SBC rather than the carrier.
The Trap: Assuming SIP 487 indicates carrier-side failure. Engineers frequently open tickets with carriers when the error is locally generated by CXone’s timeout logic. Misdiagnosing this leads to unnecessary trunk renegotiation, wasted troubleshooting cycles, and unchanged dialer performance. Always verify CANCEL origin in the SIP trace before contacting the carrier.
Architectural Reasoning: SIP transaction state machines are strictly time-bound. The UAC enters the CALLING state upon INVITE transmission and expects a provisional response within the T1 timer window (typically 500ms, with retransmissions up to 4 seconds per RFC 3261). CXone’s dialer engine overrides these defaults with campaign-level setup timeouts. When carrier latency pushes the first provisional response beyond the dialer’s configured threshold, the engine aborts the transaction to free dialer slots. Aligning diagnostic data with actual RTT prevents reactive configuration changes and ensures timeout tuning targets the correct network segment.
2. Tune CXone Outbound Dialer Timeout Thresholds
After confirming latency-driven CANCEL generation, adjust the dialer’s call setup timeouts to accommodate the carrier’s propagation delay. CXone stores these values at the campaign level within the outbound configuration. The critical fields are initialResponseTimeout, ringTimeout, and carrierTimeout. Default values typically range from 2000ms to 2500ms for initial response. For high-latency routes, increase the initial response threshold to 3500ms or 4000ms.
Update the campaign configuration via the outbound API. The payload must preserve existing pacing parameters while modifying only the timeout fields to avoid unintended algorithmic shifts.
PUT /api/v2/outbound/campaigns/{campaignId}
Content-Type: application/json
Authorization: Bearer {access_token}
{
"name": "HighLatencyCarrierCampaign",
"type": "predictive",
"settings": {
"callSetupTime": 4000,
"initialResponseTimeout": 3800,
"ringTimeout": 15000,
"carrierTimeout": 30000,
"pacingFactor": 0.75,
"maxConcurrentCalls": 500
},
"status": "active"
}
Apply this configuration to campaigns exclusively using the high-latency trunk group. Do not modify global dialer defaults. Validate the change by monitoring the 487 rate over a sixty-minute window. A successful adjustment reduces 487 volume by seventy percent or more while maintaining answer rates.
The Trap: Applying timeout increases globally across all dialer campaigns. Universal timeout expansion degrades agent experience by holding dialer attempts longer on low-latency trunks. This artificially inflates call setup times, reduces effective answer rates, and causes the predictive engine to under-predict concurrent INVITEs. Scope timeout changes to specific trunk groups and dedicated campaigns.
Architectural Reasoning: Outbound dialers calculate safe concurrent INVITE volumes using historical answer rates, average setup times, and target agent idle percentages. The pacing engine assumes a predictable call setup window. When timeouts are too aggressive, the dialer drops calls before carriers answer, which the engine interprets as lower answer probability. This triggers a feedback loop that reduces pacing, increasing agent idle time. By extending initialResponseTimeout only for latent routes, you preserve the predictive model’s accuracy for low-latency trunks while accommodating carrier constraints. The carrierTimeout field should remain strict (15000ms to 30000ms) to prevent orphaned SIP transactions from consuming session table capacity.
3. Configure SIP Stack Timer Overrides & Trunk-Level Resilience
Campaign-level timeouts manage dialer slot allocation, but the underlying SIP stack must also tolerate delayed provisional responses. CXone’s telephony trunk configuration exposes SIP timer overrides that control retransmission intervals and response windows at the SBC layer. Modify the trunk configuration to align SIP stack behavior with the dialer’s new thresholds.
Target the trunk group assigned to the high-latency carrier. Update the SIP stack parameters using the telephony trunking API. The critical fields are initialResponseTimeout, finalResponseTimeout, retransmissionInterval, and sipKeepAlive.
PUT /api/v2/telephony/trunking/locations/{locationId}/trunks/{trunkId}
Content-Type: application/json
Authorization: Bearer {access_token}
{
"name": "HighLatencyCarrierTrunk",
"type": "sip",
"sipSettings": {
"initialResponseTimeout": 4000,
"finalResponseTimeout": 12000,
"retransmissionInterval": 500,
"maxRetransmissions": 7,
"sipKeepAlive": true,
"keepAliveInterval": 20000,
"cancelOnTimeout": true,
"allowProvisionalResponses": true
},
"status": "active"
}
Enable cancelOnTimeout to ensure CXone generates clean CANCEL requests rather than allowing transactions to timeout silently. Set allowProvisionalResponses to true so the SBC processes 100 Trying and 180 Ringing messages immediately upon arrival, even if they arrive after the dialer’s internal timeout window. This prevents the SBC from discarding late provisionals and incorrectly escalating to 487.
The Trap: Disabling cancelOnTimeout or suppressing CANCEL generation entirely. SIP requires explicit CANCEL messages to abort pending INVITE transactions. Suppressing CANCEL creates orphaned SIP dialogues that consume carrier session resources, trigger billing for abandoned attempts, and pollute carrier-side analytics. Always allow graceful CANCEL generation while extending the timeout window.
Architectural Reasoning: The SIP stack operates independently from the dialer pacing engine. If the dialer timeout extends to 3800ms but the SIP stack timeout remains at 2000ms, the SBC will terminate the transaction before the dialer engine processes the timeout event. This causes race conditions where the dialer attempts to send CANCEL after the SBC has already dropped the INVITE, resulting in protocol violations and carrier-side rejections. Aligning initialResponseTimeout across both the dialer campaign and the trunk SIP stack ensures consistent transaction lifecycle management. The retransmissionInterval should remain at 500ms to comply with RFC 3261 exponential backoff, while maxRetransmissions controls how many attempts the SBC makes before declaring the transaction failed.
4. Implement Carrier-Aware Routing & Fallback Logic
Timeout adjustments resolve the immediate 487 generation, but sustainable architecture requires isolating high-latency carriers from standard routing paths. CXone’s trunk group load balancing and carrier selection policies allow you to segment routes by latency profile. Create a dedicated trunk group for high-latency carriers and assign it to a specific dialer campaign with adjusted pacing parameters.
Configure the trunk group with least-outbound-calls load balancing to distribute INVITEs evenly across redundant high-latency trunks. Disable round-robin if carrier failover behavior is unpredictable. Implement fallback routing by adding a secondary trunk group containing low-latency carriers. Use CXone’s routing policies to direct calls to the fallback group when the primary group exceeds a configurable 487 threshold.
PUT /api/v2/telephony/trunking/locations/{locationId}/trunkgroups/{trunkGroupId}
Content-Type: application/json
Authorization: Bearer {access_token}
{
"name": "HighLatencyCarrierGroup",
"loadBalancingAlgorithm": "least-outbound-calls",
"fallbackTrunkGroupId": "{lowLatencyTrunkGroupId}",
"failureThreshold": {
"type": "percentage",
"metric": "callOutcome",
"value": "487",
"threshold": 15,
"windowMinutes": 10
},
"trunks": [
{"trunkId": "{trunkId1}", "weight": 1},
{"trunkId": "{trunkId2}", "weight": 1}
]
}
Assign this trunk group to the high-latency campaign configured in Step 2. The predictive dialer will now use the extended timeouts exclusively for this route. Monitor the failureThreshold metric. If 487 volume exceeds fifteen percent over a ten-minute window, CXone automatically shifts traffic to the fallback low-latency group. This prevents dialer slot exhaustion and protects agent experience.
The Trap: Routing high-latency carriers into predictive dialers without adjusting the pacingFactor. Predictive algorithms assume standard PSTN setup times. Feeding them extended setup times causes the dialer to over-predict concurrent INVITEs, leading to callback storms and agent idle time. Always reduce pacingFactor proportionally when increasing setup timeouts.
Architectural Reasoning: Outbound dialers rely on historical answer rates and setup times to calculate safe concurrent INVITE volumes. The pacing engine uses the formula: Safe INVITEs = (Agent Count * (1 + Pacing Factor)) / (1 - Estimated Answer Rate). When setup times increase, the estimated answer rate drops because calls are dropped before ringing. If the pacing factor remains unchanged, the engine continues issuing INVITEs at the previous rate, but the extended timeout holds dialer slots longer. This reduces effective throughput and increases agent idle time. Isolating high-latency routes into dedicated trunk groups allows campaign-level pacing adjustments without contaminating the global predictive model. The fallback threshold provides automatic degradation handling, ensuring that temporary carrier congestion does not cascade into dialer-wide performance loss.
Validation, Edge Cases & Troubleshooting
Edge Case 1: Predictive Dialer Over-Pacing on Latent Trunks
- The Failure Condition: 487 volume decreases after timeout tuning, but agent callback rates spike and predictive efficiency drops below eighty percent.
- The Root Cause: The pacing factor was not reduced proportionally to the extended setup timeout. The dialer continues issuing INVITEs at historical rates, but the longer timeout window holds slots, reducing actual call completions.
- The Solution: Reduce the
pacingFactorby fifteen to twenty percent for the high-latency campaign. Use the CXone Dialer Analytics dashboard to monitorPredictive EfficiencyandAgent Idle Time. Adjust incrementally until callback rates stabilize below five percent and efficiency returns to baseline.
Edge Case 2: Asymmetric Routing Masking True Latency
- The Failure Condition: Outbound INVITEs hit high-latency paths, but inbound
100 Tryingresponses take a different, faster route, causing CXone to misinterpret timing and still generate premature CANCELs. - The Root Cause: BGP peering asymmetry or carrier B2BUA misconfiguration routes request and response traffic through different network segments. CXone measures latency based on response arrival, but the actual INVITE propagation delay remains hidden.
- The Solution: Force symmetric routing by configuring the carrier to honor
SIP-RouteandRecord-Routeheaders. Validate path consistency usingGET /api/v2/telephony/monitoring/sip-tracesand compareViaheader timestamps. If the carrier cannot enforce symmetry, implement a dedicated SBC or SIP proxy at the CXone edge to normalize response timing before dialer evaluation.
Edge Case 3: SIP 487 vs SIP 503 Confusion in Logs
- The Failure Condition: Call logs consistently show 487, but carrier traces indicate
503 Service Unavailableresponses are being sent. - The Root Cause: CXone’s SBC receives the 503 after the internal timeout fires. The SBC translates late 5xx responses to 487 to maintain transaction state consistency, masking the true carrier failure code.
- The Solution: Enable
sipDebugLoggingon the trunk configuration to capture raw SIP messages. ExtendfinalResponseTimeoutto 15000ms to allow late 5xx responses to arrive before CANCEL generation. Update monitoring dashboards to parse raw SIP traces rather than relying solely on call outcome codes. This reveals carrier-side throttling or capacity constraints that require contract renegotiation rather than dialer tuning.