{"record":{"id":"3096a3dac78cd2e2","repo":"shadowsocks/shadowsocks-windows","slug":"no-server-configured","errorCode":null,"errorMessage":"No server configured","messagePattern":"No server configured","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"shadowsocks-csharp/Controller/Service/TCPRelay.cs","lineNumber":264,"sourceCode":"        // TODO: decouple controller\r\n        public TCPHandler(ShadowsocksController controller, Configuration config, Socket socket)\r\n        {\r\n            _controller = controller;\r\n            _config = config.proxy;\r\n            _connection = socket;\r\n            _proxyTimeout = config.proxy.proxyTimeout * 1000;\r\n            _serverTimeout = config.GetCurrentServer().timeout * 1000;\r\n\r\n            lastActivity = DateTime.Now;\r\n        }\r\n\r\n        public void CreateRemote()\r\n        {\r\n            Server server = _controller.GetAServer(IStrategyCallerType.TCP, (IPEndPoint)_connection.RemoteEndPoint,\r\n                _destEndPoint);\r\n            if (server == null || server.server == \"\")\r\n            {\r\n                throw new ArgumentException(\"No server configured\");\r\n            }\r\n\r\n            _encryptor = EncryptorFactory.GetEncryptor(server.method, server.password);\r\n\r\n            _server = server;\r\n\r\n            /* prepare address buffer length for AEAD */\r\n            Logger.Trace($\"_addrBufLength={_addrBufLength}\");\r\n            _encryptor.AddrBufLength = _addrBufLength;\r\n        }\r\n\r\n        public void Start(byte[] firstPacket, int length)\r\n        {\r\n            _firstPacket = firstPacket;\r\n            _firstPacketLength = length;\r\n            HandshakeReceive();\r\n        }\r\n\r","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/shadowsocks/shadowsocks-windows/blob/891d971682eefcaa2e640258d3b352a3ad3b2233/shadowsocks-csharp/Controller/Service/TCPRelay.cs#L246-L282","documentation":"Thrown as ArgumentException from TCPRelay.CreateRemote when GetAServer returns null or a server whose `server` field is empty, meaning no usable upstream Shadowsocks server is available for the connection. This is a configuration/availability failure: the strategy and server list could not select a target. It fires before the encryptor is created.","triggerScenarios":"The server list is empty or every server was filtered out by the active strategy (e.g. all marked unreachable by a high-availability strategy); the selected server has a blank address field due to a malformed config; GetAServer returned null because no server matched the caller/endpoint criteria.","commonSituations":"Fresh install with no servers added; user deleted all servers; HA strategy disabled all servers after repeated failures; a manually edited gui-config.json left a server with an empty address.","solutions":["Add at least one valid server in the configuration (address, port, method, password).","If using a strategy, check that it has not disabled all servers; switch to a simpler strategy or reset server reachability.","Validate gui-config.json for any server entries with an empty `server` field and fix or remove them.","Ensure GetAServer's caller/endpoint logic can actually select from the configured list."],"exampleFix":"// before\nServer server = _controller.GetAServer(IStrategyCallerType.TCP, (IPEndPoint)_connection.RemoteEndPoint, _destEndPoint);\nif (server == null || server.server == \"\")\n    throw new ArgumentException(\"No server configured\");\n\n// after: keep the connection open with a clearer message and a guard upstream\nif (server == null || string.IsNullOrWhiteSpace(server.server))\n    throw new ArgumentException(\"No server configured (add a server or check HA strategy state)\");","handlingStrategy":"validation","validationCode":"// Ensure a usable server exists before relaying\nif (_controller.GetCurrentServer() is null || string.IsNullOrWhiteSpace(_controller.GetCurrentServer()?.server))\n    return; // drop the connection cleanly instead of throwing","typeGuard":"bool HasUsableServer(Configuration c) =>\n    c.configs != null && c.configs.Any(s => !string.IsNullOrWhiteSpace(s?.server));","tryCatchPattern":"try { relay.CreateRemote(); }\ncatch (ArgumentException ex) when (ex.Message == \"No server configured\")\n{ /* close the connection, notify UI to add a server */ }","preventionTips":["Validate config has at least one non-empty server at load time.","Show a clear UI state when no server is selectable rather than throwing per-connection.","Reset HA-strategy disabled flags when servers are edited."],"tags":["configuration","server","strategy","tcp-relay"],"backgroundTag":null,"analyzedSha":"891d971682eefcaa2e640258d3b352a3ad3b2233","analyzedAt":"2026-08-13T10:12:34.434Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}