{"record":{"id":"e3c658f53bae884c","repo":"microsoft/aspire","slug":"the-provided-extension-socket-path-needs-two-valid-parts","errorCode":null,"errorMessage":"The provided extension socket path needs two valid parts.","messagePattern":"The provided extension socket path needs two valid parts\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Cli/Backchannel/ExtensionBackchannel.cs","lineNumber":261,"sourceCode":"                return;\n            }\n\n            try\n            {\n                using var activity = _activitySource.StartActivity();\n\n                if (_rpcTaskCompletionSource.Task.IsCompleted)\n                {\n                    throw new InvalidOperationException($\"Already connected to {Name} backchannel.\");\n                }\n\n                _logger.LogDebug(\"Connecting to {Name} backchannel at {SocketPath}\", Name, endpoint);\n                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);\n                var addressParts = endpoint.Split(':');\n                if (addressParts.Length != 2 || !int.TryParse(addressParts[1], out var port) || port <= 0 ||\n                    port > 65535)\n                {\n                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ErrorStrings.InvalidSocketPath, endpoint));\n                }\n\n                await socket.ConnectAsync(addressParts[0], port, cancellationToken);\n                _logger.LogDebug(\"Connected to {Name} backchannel at {SocketPath}\", Name, endpoint);\n\n                var stream = new SslStream(new NetworkStream(socket, true),\n                    leaveInnerStreamOpen: true,\n                    userCertificateValidationCallback: (_, c, _, e) =>\n                    {\n                        // Server certificate is already considered valid.\n                        if (e == SslPolicyErrors.None)\n                        {\n                            return true;\n                        }\n\n                        if (c == null)\n                        {\n                            return false;","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Cli/Backchannel/ExtensionBackchannel.cs#L243-L279","documentation":"ConnectAsync parses the extension endpoint as host:port by splitting on ':'. The endpoint must yield exactly two parts with a valid port (integer, 1-65535); otherwise it throws an ArgumentException with this message (ErrorStrings.InvalidSocketPath), since TCP endpoints require both a host and a port.","triggerScenarios":"Calling ConnectAsync with ASPIRE_EXTENSION_ENDPOINT set to a value that is not 'host:port' — e.g., a bare hostname, a full URL (https://host:port), an IPv6 literal, or a port outside 1-65535.","commonSituations":"Users paste the extension's full URL (with scheme or path) into ASPIRE_EXTENSION_ENDPOINT instead of host:port, or the token/tokenless env var is corrupted or truncated.","solutions":["Set ASPIRE_EXTENSION_ENDPOINT to a plain 'host:port' pair, e.g. 127.0.0.1:54321 — no scheme, no path.","Re-copy the endpoint exactly as reported by the Aspire VS Code extension.","If IPv6 is involved, format the endpoint as expected by the parser (avoid bracketed literals; use an IPv4/hostname:port if supported)."],"exampleFix":"// before\nexport ASPIRE_EXTENSION_ENDPOINT=https://127.0.0.1:54321\n\n// after\nexport ASPIRE_EXTENSION_ENDPOINT=127.0.0.1:54321","handlingStrategy":"validation","validationCode":"var endpoint = Environment.GetEnvironmentVariable(\"ASPIRE_EXTENSION_ENDPOINT\");\nif (endpoint is null ||\n    endpoint.Split(':') is not [var host, var portStr] ||\n    !int.TryParse(portStr, out var port) || port is <= 0 or > 65535)\n{\n    throw new ArgumentException($\"ASPIRE_EXTENSION_ENDPOINT must be 'host:port', got '{endpoint}'.\");\n}","typeGuard":"bool isValidEndpoint = endpoint?.Split(':') is [_, var p] && int.TryParse(p, out var pt) && pt is > 0 and <= 65535;","tryCatchPattern":"try { await backchannel.ConnectAsync(endpoint, ct); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"two valid parts\"))\n{ /* re-read endpoint from the extension as host:port */ }","preventionTips":["Set ASPIRE_EXTENSION_ENDPOINT as plain 'host:port' — no scheme, no path, no brackets.","Copy the endpoint value directly from the extension's reported endpoint.","Validate the endpoint format at configuration-load time."],"tags":["endpoint","parsing","configuration","extension"],"backgroundTag":"invalid-argument-format","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}