-
Notifications
You must be signed in to change notification settings - Fork 268
Description
I’m running a Microsoft Graph Calling/Recording Bot (Application-Hosted Media) as a self-hosted .NET 6 app on Windows Server using Kestrel (console exe / Windows Service).
The app starts and Kestrel binds correctly, ICommunicationsClient begins building, but during CommunicationsClientBuilder.Build() the SDK calls MediaPlatform.Initialize() and it fails with:
SkypeMediaException: Address already in use
This happens even though Kestrel and MediaPlatform are configured on different ports.
Environment
OS: Windows Server (self-hosted)
Runtime: .NET 6.0
Hosting: Kestrel (NOT IIS)
Scenario: Application-Hosted Media (Graph Calling/Recording Bot)
SDK Versions
Microsoft.Graph.Communications.Calls.Media: 1.2.0.5304
Microsoft.Graph.Communications.Client: 1.2.0.5304
Microsoft.Graph.Communications.Core: 1.2.0.5304
Microsoft.Skype.Bots.Media: 1.31.0.225-preview
Expected behavior
Kestrel binds http://127.0.0.1:5000 for bot callbacks/notifications
MediaPlatform binds media ports starting from 8445
Both should coexist without conflicts
MediaPlatform.Initialize() should succeed
Actual behavior
Kestrel starts successfully on port 5000
CommunicationsClientBuilder.Build() triggers media init
Media init fails with Address already in use
MediaPlatform Settings (Startup.cs)
var mediaPlatformSettings = new MediaPlatformSettings
{
ApplicationId = "<APP_ID>",
MediaPlatformInstanceSettings = new MediaPlatformInstanceSettings
{
CertificateThumbprint = "<**************>",
InstanceInternalPort = ******,
InstancePublicPort = **,
InstancePublicIPAddress = IPAddress.Any,
ServiceFqdn = "bot.example.com",
MediaPortRange = new PortRange(, ****)
}
};
var notificationUrl = new Uri("https://bot.example.com/callback");
var serviceBaseUrl = new Uri("https://127.0.0.1:9443/");
var builder = new CommunicationsClientBuilder(
"MyBot",
"<APP_ID>",
graphLogger)
.SetAuthenticationProvider(authProvider)
.SetNotificationUrl(notificationUrl)
.SetServiceBaseUrl(serviceBaseUrl)
.SetMediaPlatformSettings(mediaPlatformSettings);
var client = builder.Build(); // ❌ fails: Address already in use
Initialization timing
I tried deferring MediaPlatform initialization until after Kestrel is listening:
public class MediaPlatformHostedService : IHostedService
{
public Task StartAsync(CancellationToken cancellationToken)
{
_lifetime.ApplicationStarted.Register(() =>
{
var communicationsClient =
_serviceProvider.GetRequiredService();
});
return Task.CompletedTask;
}
}
But Build() still fails once it reaches MediaPlatform.Initialize().
Logs (simplified)
[INF] Kestrel is listening on port 5000
[INF] Initializing Media Platform
[INF] InstanceInternalPort=8445, InstancePublicPort=8445
[CRT] SkypeMediaException: Address already in use
Checks already done
Certificate installed in LocalMachine\My and thumbprint is correct
Firewall rules allow UDP traffic for the media range
Verified no other process is using ports 5000, 8445, or 9443
Running as admin / service account with required permissions
Questions
ServiceBaseUrl
Does SetServiceBaseUrl() affect local port binding?
If I set https://127.0.0.1:internal-port/, can MediaPlatform attempt to bind to ***** internally?
What is the correct ServiceBaseUrl for a Kestrel self-hosted bot?
Should it match the public bot URL (e.g., https://bot.example.com/) instead of localhost?
Windows / HTTP.sys
Can there be a conflict with HTTP.sys?
Do Kestrel + MediaPlatform share URLACL reservations?
Does MediaPlatform require “exclusive” binding behavior that can collide even when ports differ?
Port usage rules
Are InstanceInternalPort and InstancePublicPort both being 8445 correct?
Should MediaPortRange start at a different port than InstanceInternalPort?
Initialization behavior
Does MediaPlatform.Initialize() bind ports immediately during Build()?
Is there any supported way to separate “build client” from “bind media sockets”?
Known issues / workarounds
Any known bugs or constraints when running MediaPlatform alongside Kestrel (non-IIS) on Windows Server?
What I’m asking for
The correct SetServiceBaseUrl() value for Kestrel self-hosted deployments
Confirmation of whether MediaPlatform binds ports based on ServiceBaseUrl or only from InstanceInternalPort / MediaPortRange
A recommended port layout to avoid collisions
Any Windows-specific gotchas (HTTP.sys reservations, excluded port ranges, etc.)