microsoftgraph / microsoftgraph/microsoft-graph-comms-samples

Bot fails to join Teams meeting with error 500#1203002 (media negotiation failure) on GCP despite correct configuration

Open
#855 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
253
Forks
275
Avg merge
1d 5h
Merged PRs (30d)
1

Description

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

  1. Bot receives join request via /api/call/join endpoint
  2. Fetches call details from Graph API successfully
  3. Extracts meeting token successfully
  4. Calls CommunicationsClient.Calls().AddAsync() with TokenMeetingInfo
  5. Receives "Establishing" notification
  6. 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

  1. ✅ Dynamic certificate discovery by subject name
  2. ✅ Verified certificate chain completeness
  3. ✅ Updated SSL binding to match certificate
  4. ✅ Changed StreamDirection from Recvonly to Sendrecv
  5. ✅ Set ReceiveUnmixedMeetingAudio = true
  6. ✅ Passed MediaPlatformInstanceId to CreateMediaSession
  7. ✅ Verified UDP connectivity with nmap
  8. ✅ Confirmed firewall rules allow all required ports

Similar Issues

We've reviewed these related issues but none provided a solution:

  • #750 — Intermittent failures (ours is 100% consistent)
  • #772 — Same error code but different root cause
  • Microsoft Q&A 5584569 — Suggests certificate chain issues (verified not our case)

Questions

  1. Is GCP NAT fundamentally incompatible with application-hosted media bots?
  2. Are there additional diagnostic logs we can enable to see why media negotiation fails?
  3. 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)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the /api/call/join entry point and the CommunicationsClient.Calls().AddAsync() call, then review the MediaPlatformSettings network and certificate values described here. Compare the GCP NAT setup with the platform's documented hosting requirements and investigate available diagnostic logging. Done means establishing why media negotiation terminates and documenting a confirmed compatible configuration or incompatibility.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, google-cloud
Domain
audio-video-rtc, cloud, networking
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.