We are experiencing a recurring issue in our current application where users face a wave of mass disconnects from Twilio. The application is built with AngularJS on the client side and .NET on the backend. We are using the Twilio Voice SDK V1.14.0 for most users, with a small number (less than 10) using V2.12.3.
The Issue
Multiple times a day, around 50 out of approximately 130 online users experience unexpected disconnections from Twilio. The disconnects occur suddenly, and users lose their connection through the Twilio Voice SDK. These disconnections last for about a minute and then stop, without any apparent time pattern. They tend to happen more frequently in the morning.
However, two other parallel websocket connections remain stable:
A SignalR connection that handles our business logic.
A connection to Twilio TaskRouter.
Neither of these connections is affected when the Voice SDK disconnects.
We have been using these methods and configurations for over three years without encountering such a severe issue with disconnections. Recently, we migrated many users from Twilio Voice SDK V1 to V2, but the issue persists for both versions.
Each user operates from their own PC and work equipment. While they have no issues with 99% of their calls, these disconnections occur with specific calls.
Here’s the code:
let deviceParams = {
codecPreferences: ["opus", "pcmu"],
closeProtection: false,
fakeLocalDTMF: true,
audioConstraints: {
mandatory: {
googAutoGainControl: false
}
},
};
if ($scope.model.isUsingNewTwilioLibraryVersion) {
deviceParams.enableImprovedSignalingErrorPrecision = true;
deviceParams.maxCallSignalingTimeoutMs = 6000;
}
$scope.model.phoneCapabilityToken = '' // this comes from the backend
// V1 implementation
$scope.twilio.device = twilioDeviceManager.getDeviceV1();
$scope.twilio.device.on("ready", deviceOnReady);
$scope.twilio.device.on("error", deviceOnError);
$scope.twilio.device.on("connect", deviceOnConnect);
$scope.twilio.device.on("disconnect", deviceOnDisconnect);
$scope.twilio.device.on("cancel", deviceOnCancel);
$scope.twilio.device.on("offline", deviceOnOffline);
$scope.twilio.device.on("incoming", deviceOnIncoming);
$scope.twilio.device.setup($scope.model.phoneCapabilityToken, deviceParams);
// V2 implementation
$scope.twilio.device = twilioDeviceManager.getDeviceV2($scope.model.phoneCapabilityToken, deviceParams);
$scope.twilio.device.on("registered", deviceOnRegistered);
$scope.twilio.device.on("registering", deviceOnRegistering);
$scope.twilio.device.on("unregistered", deviceOnUnregistered);
$scope.twilio.device.on("error", deviceOnError);
$scope.twilio.device.on("destroyed", deviceOnDestroyed);
$scope.twilio.device.on("incoming", deviceOnIncoming);
$scope.twilio.device.on('tokenWillExpire', deviceOnTokenWillExpire)
$scope.twilio.device.register();
// making a call
let targetPhoneNumber = '1231233441'
let connectParams = { targetPhoneNumber: '' };
// V1
$scope.twilio.device.connect(connectParams);
// V2
this.twilioDevice.connect({ params: connectParams })
.then((call) => {
call.on('accept', c => {
$scope.deviceOnConnectCommon(c)
})
})
.catch((error) => {
console.log(error);
})
Logs from Twilio Device SDK
Here are the logs we captured from the Twilio Voice SDK during the disconnects:
[2025-01-10 09:43:56.667] [info] device.on.connect
[2025-01-10 09:44:00.683] [info] connection.warning high-packet-loss
[2025-01-10 09:44:03.679] [info] connection.warning high-packets-lost-fraction
[2025-01-10 09:44:08.688] [info] connection.warning low-bytes-received
[2025-01-10 09:44:11.974] [info] connection.warning ice-connectivity-lost
[2025-01-10 09:44:11.982] [info] connection.reconnecting ConnectionError: ConnectionError (53405): Media connection failed.
at ConnectionError.TwilioError [as constructor] (<anonymous>:1:158062)
at new ConnectionError (<anonymous>:1:150484)
at Call._this._onMediaFailure (<anonymous>:1:46317)
at Call._this._mediaHandler.ondisconnected (<anonymous>:1:56684)
at PeerConnection._onMediaConnectionStateChange (<anonymous>:1:216760)
at pc.oniceconnectionstatechange (<anonymous>:1:224502)
[2025-01-10 09:44:12.679] [info] connection.warning-cleared high-packets-lost-fraction
[2025-01-10 09:44:13.460] [info] connection.reconnecting ConnectionDisconnected: ConnectionDisconnected (53001): Raised whenever the signaling connection is unexpectedly disconnected.
at ConnectionDisconnected.TwilioError [as constructor] (<anonymous>:1:158062)
at new ConnectionDisconnected (<anonymous>:1:146883)
at Call._this._onTransportClose (<anonymous>:1:50890)
at emitNone (<anonymous>:1:282216)
at PStream.emit (<anonymous>:1:283662)
at PStream._handleTransportClose (<anonymous>:1:185601)
at emitNone (<anonymous>:1:282216)
at WSTransport.emit (<anonymous>:1:283662)
at WSTransport._closeSocket (<anonymous>:1:275290)
at <anonymous>:1:277053
[2025-01-10 09:44:13.462] [info] device.on.unregistered
[2025-01-10 09:44:15.680] [info] connection.warning-cleared high-packet-loss
[2025-01-10 09:44:18.557] [info] connection.reconnecting ConnectionDisconnected: ConnectionDisconnected (53001): Raised whenever the signaling connection is unexpectedly disconnected.
at ConnectionDisconnected.TwilioError [as constructor] (<anonymous>:1:158062)
at new ConnectionDisconnected (<anonymous>:1:146883)
at Call._this._onTransportClose (<anonymous>:1:50890)
at emitNone (<anonymous>:1:282216)
at PStream.emit (<anonymous>:1:283662)
at PStream._handleTransportClose (<anonymous>:1:185601)
at emitNone (<anonymous>:1:282216)
at WSTransport.emit (<anonymous>:1:283662)
at WSTransport._closeSocket (<anonymous>:1:275290)
at <anonymous>:1:276292
[2025-01-10 09:44:18.748] [info] workerOnActivityUpdate Offline
[2025-01-10 09:44:23.679] [info] connection.warning constant-audio-input-level
[2025-01-10 09:44:23.763] [info] connection.reconnecting ConnectionDisconnected: ConnectionDisconnected (53001): Raised whenever the signaling connection is unexpectedly disconnected.
at ConnectionDisconnected.TwilioError [as constructor] (<anonymous>:1:158062)
at new ConnectionDisconnected (<anonymous>:1:146883)
at Call._this._onTransportClose (<anonymous>:1:50890)
at emitNone (<anonymous>:1:282216)
at PStream.emit (<anonymous>:1:283662)
at PStream._handleTransportClose (<anonymous>:1:185601)
at emitNone (<anonymous>:1:282216)
at WSTransport.emit (<anonymous>:1:283662)
at WSTransport._closeSocket (<anonymous>:1:275290)
at <anonymous>:1:276292
[2025-01-10 09:44:23.810] [info] device.on.error {
code: 31009,
message: 'TransportError (31009): No transport available to send or receive messages'
}
[2025-01-10 09:44:27.061] [info] device.on.error {
code: 31009,
message: 'TransportError (31009): No transport available to send or receive messages'
}
[2025-01-10 09:44:27.066] [info] connection.warning ice-connectivity-lost
[2025-01-10 09:44:28.681] [info] connection.warning-cleared constant-audio-input-level
[2025-01-10 09:44:29.302] [info] connection.reconnecting ConnectionDisconnected: ConnectionDisconnected (53001): Raised whenever the signaling connection is unexpectedly disconnected.
at ConnectionDisconnected.TwilioError [as constructor] (<anonymous>:1:158062)
at new ConnectionDisconnected (<anonymous>:1:146883)
at Call._this._onTransportClose (<anonymous>:1:50890)
at emitNone (<anonymous>:1:282216)
at PStream.emit (<anonymous>:1:283662)
at PStream._handleTransportClose (<anonymous>:1:185601)
at emitNone (<anonymous>:1:282216)
at WSTransport.emit (<anonymous>:1:283662)
at WSTransport._closeSocket (<anonymous>:1:275290)
at <anonymous>:1:276292
[2025-01-10 09:44:34.567] [info] connection.reconnecting ConnectionDisconnected: ConnectionDisconnected (53001): Raised whenever the signaling connection is unexpectedly disconnected.
at ConnectionDisconnected.TwilioError [as constructor] (<anonymous>:1:158062)
at new ConnectionDisconnected (<anonymous>:1:146883)
at Call._this._onTransportClose (<anonymous>:1:50890)
at emitNone (<anonymous>:1:282216)
at PStream.emit (<anonymous>:1:283662)
at PStream._handleTransportClose (<anonymous>:1:185601)
at emitNone (<anonymous>:1:282216)
at WSTransport.emit (<anonymous>:1:283662)
at WSTransport._closeSocket (<anonymous>:1:275290)
at <anonymous>:1:276292
[2025-01-10 09:44:38.799] [info] device.on.error {
code: 20101,
message: 'AccessTokenInvalid (20101): Twilio was unable to validate your Access Token'
}
Additional Information
We believe the AccessTokenInvalid error is not accurate. We generate tokens with a 10-hour validity, and these disconnects are occurring within an hour of starting the session.
Users do not lose their connection to our server or the Twilio TaskRouter during these disconnections.
The server metrics show no performance issues (CPU, memory, database performance, etc.).
User Demographics
All affected users are from the Philippines.
They are connecting to the Twilio edge in Singapore.
As far as we know, they all share the same ISP (though we are not 100% certain).
The calls are being connected to Twilio Conferences created in the US1 region.
Environment Details
The application runs both as an executable created with Electron and in web browsers. The issue occurs in both environments.
No infrastructure or code changes were made prior to this issue starting.
The issue has been occurring for about a week.
Question
Has anyone experienced a similar issue with Twilio Voice SDK disconnecting in mass waves? Could this be related to Twilio edge locations or ISP-related issues? Any guidance on how to diagnose and resolve this problem would be highly appreciated.
We reviewed our infrastructure, server performance, and Twilio setup. No recent changes were made, and all metrics are stable. We expected users to stay connected to Twilio Voice SDK without interruptions. However, we noticed frequent mass disconnects, even though other connections (SignalR, TaskRouter) remain unaffected. We expected stability similar to what we’ve had for over 3 years.
We also migrated from Twilio Voice SDK V1 to V2 but the problem persisted.
Is there something I can change from my code to make this better?