CoplayDev/unity-mcp · error · InvalidOperationException

Port {port} is already in use.

Error message

Port {port} is already in use.

What it means

After the positive-port check passes, SetPreferredPort probes the port via IsPortAvailable (a TcpListener bind test on IPAddress.Loopback). If the port is already bound or otherwise unavailable, it throws InvalidOperationException. Note: the method's doc comment mentions choosing the next available port, but this specific method strictly refuses a busy port.

Source

Thrown at MCPForUnity/Editor/Helpers/PortManager.cs:99

        /// which distinguishes a domain-reload socket-release race from a foreign occupant (#1173).
        /// </summary>
        public static bool ShouldAbandonBusyPort(double busyForSeconds)
            => busyForSeconds >= BusyPortFallbackWindowSeconds;

        /// <summary>
        /// Persist a user-selected port and return the value actually stored.
        /// If <paramref name="port"/> is unavailable, the next available port is chosen instead.
        /// </summary>
        public static int SetPreferredPort(int port)
        {
            if (port <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(port), "Port must be positive.");
            }

            if (!IsPortAvailable(port))
            {
                throw new InvalidOperationException($"Port {port} is already in use.");
            }

            SavePort(port);
            return port;
        }

        /// <summary>
        /// Find an available port starting from the default port
        /// </summary>
        /// <returns>Available port number</returns>
        private static int FindAvailablePort()
        {
            // Always try default port first
            if (IsPortAvailable(DefaultPort))
            {
                if (IsDebugEnabled()) McpLog.Info($"Using default port {DefaultPort}");
                return DefaultPort;
            }

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Stop the conflicting process occupying the port, or choose a different port.
  2. If you want automatic fallback rather than a hard refusal, use the FindAvailablePort path instead of SetPreferredPort.
  3. Check for orphaned server processes after a crash before retrying.
Defensive patterns

Strategy: fallback

Validate before calling

if (!PortManager.IsPortAvailable(port))
    throw new InvalidOperationException($"Port {port} is busy; stop the owning process or choose another.");
PortManager.SetPreferredPort(port);

Try / catch

try { return PortManager.SetPreferredPort(port); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already in use"))
{
    // Fall back to automatic port discovery instead of refusing.
    return FindAvailablePortWithFallback();
}

Prevention

When it happens

Trigger: Another process (a Unity instance, the Python MCP server, a dev server) already bound the port; a socket lingering in TIME_WAIT; the OS reserving the port.

Common situations: Multiple Unity/Server instances competing for the default port; a leftover process from a crashed session; the port held by an unrelated local service.

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/28d84571c4cc3ef6. Report an issue: GitHub.