stride3d/stride · error · InvalidOperationException
Cannot listen on an unusable interface. Check the IsUsable…
Error message
Cannot listen on an unusable interface. Check the IsUsable property before attemping to bind.
What it means
TcpSocketListener.StartListeningAsync throws InvalidOperationException when asked to bind to an ICommsInterface whose IsUsable property is false. Stride requires callers to verify interface usability (e.g. interface is up, has an address) before binding a listener to it.
Solutions
- Check listenOn.IsUsable before calling StartListeningAsync and pick a usable interface
- If listenOn is null it binds to IPAddress.Loopback; pass null or a usable interface instead
- Re-enumerate NetworkInterface/comms interfaces at listen time instead of caching old ones
- Handle the exception by falling back to loopback or another usable interface
Example fix
// before
await listener.StartListeningAsync(port, cachedInterface);
// after
if (cachedInterface.IsUsable)
await listener.StartListeningAsync(port, cachedInterface);
else
await listener.StartListeningAsync(port); Defensive patterns
Strategy: validation
Validate before calling
if (listenOn != null && !listenOn.IsUsable) listenOn = null; // fall back to loopback await listener.StartListeningAsync(port, listenOn);
Type guard
bool CanBindOn(ICommsInterface i) => i == null || i.IsUsable;
Try / catch
try { await listener.StartListeningAsync(port, iface); }
catch (InvalidOperationException) { await listener.StartListeningAsync(port); } Prevention
- Always check IsUsable before binding to a specific interface
- Re-enumerate interfaces at listen time instead of caching
- Prefer null (loopback) for local-only servers
- Wrap listen setup in try-catch with interface fallback
When it happens
Trigger: Calling StartListeningAsync(port, listenOn) with a specific interface instance that is down, disconnected, or otherwise marked not usable.
Common situations: Binding to a WiFi interface that dropped; binding to a VPN/ethernet adapter that went offline; caching an ICommsInterface from startup and using it after the network changed.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Could not connect to server
- Connection router did not connect back to our listen socket
- Invalid ack
- Socket closed
- Could not restore package
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/dfc6061d2914c364.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Engine/Engine/Network/Sockets.Implementation.NET/TcpSocketListener.cs:57
/// Fired when a new TCP connection has been received.
/// Use the <code>SocketClient</code> property of the <code>TcpSocketListenerConnectEventArgs</code>
/// to get a <code>TcpSocketClient</code> representing the connection for sending and receiving data.
/// </summary>
public EventHandler<TcpSocketListenerConnectEventArgs> ConnectionReceived { get; set; }
/// <summary>
/// Binds the <code>TcpSocketListener</code> to the specified port and listens for TCP connections.
/// </summary>
/// <param name="port">The port to listen on.</param>
/// <param name="listenOn">The <code>CommsInterface</code> to listen on. If unspecified, binds to the loopback interface.</param>
/// <param name="inheritHandle">Allows handle inheritance. Might be ignored depending on platform.</param>
/// <returns></returns>
public Task StartListeningAsync(int port, ICommsInterface listenOn = null, bool inheritHandle = false)
{
return Task.Run(() =>
{
if (listenOn != null && !listenOn.IsUsable)
throw new InvalidOperationException("Cannot listen on an unusable interface. Check the IsUsable property before attemping to bind.");
var ipAddress = listenOn != null ? ((CommsInterface)listenOn).NativeIpAddress : IPAddress.Loopback;
_listenCanceller = new CancellationTokenSource();
_backingTcpListener = new TcpListener(ipAddress, port);
_backingTcpListener.Start();
if (Platform.Type == PlatformType.Windows && !inheritHandle)
SetHandleInformation(_backingTcpListener.Server.Handle, HANDLE_FLAGS.Inherit, HANDLE_FLAGS.None);
WaitForConnections(_listenCanceller.Token);
});
}
/// <summary>
/// Stops the <code>TcpSocketListener</code> from listening for new TCP connections.
/// This does not disconnect existing connections.View on GitHub (pinned to 96fad776d2)