Teams Application-Hosted Media Bot: 500#1203002 on GCP NAT — Call Terminates at "Establishing"
We're experiencing a persistent Server Internal Error. DiagCode: 500#1203002 when attempting to join Teams meetings with an application-hosted media bot. The call progresses to "Establishing" state but immediately terminates with a media negotiation error.
Environment Details
Platform:
- Hosting: Google Cloud Platform (GCP) VM
- OS: Windows Server
- .NET Version: .NET 8.0
- VM Configuration:
- Internal IP:
10.x.x.x (private)
- External IP: NAT'd public IP
- Custom DNS FQDN pointing to public IP
SDK Versions:
<PackageReference Include="Microsoft.Graph.Communications.Calls" Version="1.2.0.*" />
<PackageReference Include="Microsoft.Graph.Communications.Calls.Media" Version="1.2.0.*" />
<PackageReference Include="Microsoft.Graph.Communications.Common" Version="1.2.0.*" />
<PackageReference Include="Microsoft.Graph.Communications.Core" Version="1.2.0.*" />
<PackageReference Include="Microsoft.Skype.Bots.Media" Version="1.31.0.225-preview" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.*" />
Configuration Verified
We've systematically verified all standard requirements:
Certificate:
- ✅ CA-signed certificate
- ✅ Has private key
- ✅ Complete certificate chain
- ✅ Not expired
- ✅ Bound to port 8445 via netsh
- ✅ Certificate uses RSACng provider
Network:
- ✅ TCP port 8445 listening and accessible
- ✅ UDP ports 41000–41999 configured in firewall
- ✅ GCP firewall rules allow inbound TCP 8445 and UDP 41000–41999
- ✅ nmap confirms UDP port 41000 is
open|filtered (not blocked)
- ✅ Windows Firewall configured correctly
MediaPlatformSettings:
new MediaPlatformSettings
{
ApplicationId = appId,
MediaPlatformInstanceSettings = new MediaPlatformInstanceSettings
{
CertificateThumbprint = "<your-cert-thumbprint>",
InstanceInternalPort = 8445,
InstancePublicIPAddress = IPAddress.Parse("<your-public-ip>"),
InstancePublicPort = 8445,
ServiceFqdn = "<your-fqdn>",
MediaPortRange = new PortRange(41000, 41999)
}
}
Audio Settings:
new AudioSocketSettings
{
StreamDirections = StreamDirection.Sendrecv,
SupportedAudioFormat = AudioFormat.Pcm16K,
ReceiveUnmixedMeetingAudio = true
}
Call Flow
- Bot receives join request via
/api/call/join endpoint
- Fetches call details from Graph API successfully
- Extracts meeting token successfully
- Calls
CommunicationsClient.Calls().AddAsync() with TokenMeetingInfo
- Receives "Establishing" notification
- Immediately receives "Terminated" with error 500#1203002
Logs
Establishing notification:
{
"@odata.type": "#microsoft.graph.commsNotification",
"changeType": "updated",
"resource": "/app/calls/<call-id>",
"resourceData": {
"@odata.type": "#microsoft.graph.call",
"state": "establishing"
}
}
Termination (within seconds):
{
"@odata.type": "#microsoft.graph.commsNotification",
"changeType": "deleted",
"resource": "/app/calls/<call-id>",
"resourceData": {
"@odata.type": "#microsoft.graph.call",
"state": "terminated",
"resultInfo": {
"@odata.type": "#microsoft.graph.resultInfo",
"code": 500,
"subcode": 1203002,
"message": "Server Internal Error. DiagCode: 500#1203002.@"
}
}
}
Key Question: GCP NAT Compatibility
The VM has a private IP with NAT to a public IP. Microsoft's documentation states:
"Each VM instance hosting an application-hosted media bot in Azure must be directly accessible from the internet using an instance-level public IP address (ILPIP)"
Question: Is GCP's NAT architecture fundamentally incompatible with the Real-time Media Platform? Our working server uses the same Azure app registration but may be on a different hosting platform.
What We've Tried
- ✅ Dynamic certificate discovery by subject name
- ✅ Verified certificate chain completeness
- ✅ Updated SSL binding to match certificate
- ✅ Changed
StreamDirection from Recvonly to Sendrecv
- ✅ Set
ReceiveUnmixedMeetingAudio = true
- ✅ Passed
MediaPlatformInstanceId to CreateMediaSession
- ✅ Verified UDP connectivity with nmap
- ✅ Confirmed firewall rules allow all required ports
Similar Issues
We've reviewed these related issues but none provided a solution:
Questions
- Is GCP NAT fundamentally incompatible with application-hosted media bots?
- Are there additional diagnostic logs we can enable to see why media negotiation fails?
- What specific network requirements does the Real-time Media Platform have beyond basic UDP connectivity?
Additional Context
CommunicationsClient creation takes ~14 seconds (seems slow but completes successfully)
- No errors in local logs — failure happens entirely on Microsoft's side
- Issue is 100% reproducible (not intermittent)
Teams Application-Hosted Media Bot:
500#1203002on GCP NAT — Call Terminates at "Establishing"We're experiencing a persistent
Server Internal Error. DiagCode: 500#1203002when attempting to join Teams meetings with an application-hosted media bot. The call progresses to "Establishing" state but immediately terminates with a media negotiation error.Environment Details
Platform:
10.x.x.x(private)SDK Versions:
Configuration Verified
We've systematically verified all standard requirements:
Certificate:
Network:
open|filtered(not blocked)MediaPlatformSettings:
Audio Settings:
Call Flow
/api/call/joinendpointCommunicationsClient.Calls().AddAsync()withTokenMeetingInfoLogs
Establishing notification:
{ "@odata.type": "#microsoft.graph.commsNotification", "changeType": "updated", "resource": "/app/calls/<call-id>", "resourceData": { "@odata.type": "#microsoft.graph.call", "state": "establishing" } }Termination (within seconds):
{ "@odata.type": "#microsoft.graph.commsNotification", "changeType": "deleted", "resource": "/app/calls/<call-id>", "resourceData": { "@odata.type": "#microsoft.graph.call", "state": "terminated", "resultInfo": { "@odata.type": "#microsoft.graph.resultInfo", "code": 500, "subcode": 1203002, "message": "Server Internal Error. DiagCode: 500#1203002.@" } } }Key Question: GCP NAT Compatibility
The VM has a private IP with NAT to a public IP. Microsoft's documentation states:
Question: Is GCP's NAT architecture fundamentally incompatible with the Real-time Media Platform? Our working server uses the same Azure app registration but may be on a different hosting platform.
What We've Tried
StreamDirectionfromRecvonlytoSendrecvReceiveUnmixedMeetingAudio = trueMediaPlatformInstanceIdtoCreateMediaSessionSimilar Issues
We've reviewed these related issues but none provided a solution:
Questions
Additional Context
CommunicationsClientcreation takes ~14 seconds (seems slow but completes successfully)