{"record":{"id":"8d70ca17133889e6","repo":"shadowsocks/shadowsocks-windows","slug":"port-0-already-in-use","errorCode":null,"errorMessage":"Port {0} already in use","messagePattern":"Port (.+?) already in use","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"shadowsocks-csharp/Controller/Service/Listener.cs","lineNumber":65,"sourceCode":"\r\n        public Listener(List<IService> services)\r\n        {\r\n            this._services = services;\r\n        }\r\n\r\n        private bool CheckIfPortInUse(int port)\r\n        {\r\n            IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();\r\n            return ipProperties.GetActiveTcpListeners().Any(endPoint => endPoint.Port == port);\r\n        }\r\n\r\n        public void Start(Configuration config)\r\n        {\r\n            this._config = config;\r\n            this._shareOverLAN = config.shareOverLan;\r\n\r\n            if (CheckIfPortInUse(_config.localPort))\r\n                throw new Exception(I18N.GetString(\"Port {0} already in use\", _config.localPort));\r\n\r\n            try\r\n            {\r\n                // Create a TCP/IP socket.\r\n                _tcpSocket = new Socket(config.isIPv6Enabled ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);\r\n                _udpSocket = new Socket(config.isIPv6Enabled ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);\r\n                _tcpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);\r\n                _udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);\r\n                IPEndPoint localEndPoint = null;\r\n                localEndPoint = _shareOverLAN\r\n                    ? new IPEndPoint(config.isIPv6Enabled ? IPAddress.IPv6Any : IPAddress.Any, _config.localPort)\r\n                    : new IPEndPoint(config.isIPv6Enabled ? IPAddress.IPv6Loopback : IPAddress.Loopback, _config.localPort);\r\n\r\n                // Bind the socket to the local endpoint and listen for incoming connections.\r\n                _tcpSocket.Bind(localEndPoint);\r\n                _udpSocket.Bind(localEndPoint);\r\n                _tcpSocket.Listen(1024);\r\n\r","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/shadowsocks/shadowsocks-windows/blob/891d971682eefcaa2e640258d3b352a3ad3b2233/shadowsocks-csharp/Controller/Service/Listener.cs#L47-L83","documentation":"Thrown by Listener.Start when CheckIfPortInUse reports that the configured localPort already has an active TCP listener in the OS. The check enumerates GetActiveTcpListeners() and looks for a matching port, so any process (including a previous Shadowsocks instance) already bound to that port will trip it. This happens before any socket is created.","triggerScenarios":"Another Shadowsocks instance is already running on the same localPort; a different application (web server, dev tool, another proxy) occupies the port; a previous instance crashed but the OS has not yet released the listening socket (TIME_WAIT/lingering); the user changed configs and the old process is still alive.","commonSituations":"Starting a second copy of the client; a service set to auto-start racing with a manually launched copy; a crashed process whose socket is held by the OS; reusing a common port like 1080 that another tool also defaults to.","solutions":["Find and stop the process holding the port (netstat -ano | findstr <port> on Windows, then taskkill the PID).","Change config.localPort to a free port.","Ensure only one instance launches at boot (disable duplicate startup entries / scheduled tasks).","If the prior process crashed, wait briefly for the OS to release the socket, then retry."],"exampleFix":"// before\nif (CheckIfPortInUse(_config.localPort))\n    throw new Exception(I18N.GetString(\"Port {0} already in use\", _config.localPort));\n\n// after: surface which process holds the port in the message\nif (CheckIfPortInUse(_config.localPort))\n    throw new Exception(I18N.GetString(\"Port {0} already in use (check netstat)\", _config.localPort));","handlingStrategy":"validation","validationCode":"// Probe the port before binding\nusing (var probe = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))\n{\n    try { probe.Bind(new IPEndPoint(IPAddress.Loopback, candidatePort)); }\n    catch (SocketException) { /* port not free */ }\n}","typeGuard":"bool IsPortLikelyFree(int port) =>\n    !IPGlobalProperties.GetIPGlobalProperties()\n        .GetActiveTcpListeners().Any(ep => ep.Port == port);","tryCatchPattern":"try { listener.Start(config); }\ncatch (Exception ex) when (ex.Message.Contains(\"already in use\"))\n{ /* prompt user to pick another port or kill the holder */ }","preventionTips":["Detect and refuse to start a second instance of the app.","Pick a non-default port to avoid collisions with common tools.","Surface the PID holding the port in the error to speed resolution."],"tags":["network","port","binding","socket","startup"],"backgroundTag":null,"analyzedSha":"891d971682eefcaa2e640258d3b352a3ad3b2233","analyzedAt":"2026-08-13T10:12:34.434Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}