{"record":{"id":"9219bd8818ea78db","repo":"Tencent/WeKnora","slug":"failed-to-start-client-w","errorCode":null,"errorMessage":"failed to start client: %w","messagePattern":"failed to start client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/mcp/client.go","lineNumber":345,"sourceCode":"\t\treturn zero, refreshErr\n\t}\n\treturn operation()\n}\n\n// Connect establishes connection to the MCP service\nfunc (c *mcpGoClient) Connect(ctx context.Context) error {\n\tif c.connected {\n\t\treturn ErrAlreadyConnected\n\t}\n\n\t_, err := oauthCall(ctx, c, func() (struct{}, error) {\n\t\treturn struct{}{}, c.client.Start(ctx)\n\t})\n\tif err != nil {\n\t\tif oerr := asOAuthRequired(err); oerr != nil {\n\t\t\treturn oerr\n\t\t}\n\t\treturn fmt.Errorf(\"failed to start client: %w\", err)\n\t}\n\tc.connected = true\n\tif c.service.TransportType == types.MCPTransportStdio {\n\t\tlogger.GetLogger(ctx).Infof(\"MCP stdio client connected: %s %v\",\n\t\t\tc.service.StdioConfig.Command, c.service.StdioConfig.Args)\n\t} else {\n\t\tlogger.GetLogger(ctx).Infof(\"MCP client connected to %s\", *c.service.URL)\n\t}\n\treturn nil\n}\n\n// Disconnect closes the connection\nfunc (c *mcpGoClient) Disconnect() error {\n\tif !c.connected {\n\t\treturn nil\n\t}\n\n\t// Close the client","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/mcp/client.go#L327-L363","documentation":"Connect wraps errors from c.client.Start(ctx) (the mark3labs client's SSE/HTTP connection establishment) with 'failed to start client'. This is where actual network problems surface: DNS failure, connection refused, TLS errors, or non-2xx handshake responses. OAuth-required conditions are intercepted first and returned unwrapped as oauth-required errors.","triggerScenarios":"Connect called on an mcpGoClient whose server URL is unreachable, DNS-unresolvable, refusing connections, presenting a bad TLS cert, or timing out (30s default or AdvancedConfig.Timeout). Not thrown when already connected (that returns ErrAlreadyConnected).","commonSituations":"MCP server down or wrong port; service URL points to an internal hostname not resolvable from the deployment; corporate proxy/TLS interception; firewall blocking egress; server returns 404 on the /sse or /mcp endpoint path.","solutions":["Verify the service URL is reachable from the runtime: curl the /sse or /mcp endpoint from inside the deployment","Check DNS, egress firewall, and proxy settings for the environment","Confirm the server actually serves the configured transport (SSE vs streamable) at that path","Inspect the wrapped cause for TLS vs connection vs HTTP-status specifics; fix cert/proxy config accordingly","Retry with backoff for transient network errors; OAuth-required responses are surfaced separately and need re-authorization"],"exampleFix":"// before\nif err := c.Connect(ctx); err != nil { return err } // no retry\n// after\nerr := retry.Do(func() error { return c.Connect(ctx) }, retry.Attempts(3), retry.Delay(time.Second),\n    retry.RetryIf(func(err error) bool { return !errors.Is(err, ErrOAuthRequired) }))","handlingStrategy":"try-catch","validationCode":"func endpointReachable(raw string, timeout time.Duration) error {\n    c := &http.Client{Timeout: timeout}\n    resp, err := c.Head(raw)\n    if err != nil { return err }\n    resp.Body.Close()\n    return nil\n} // run as a preflight/diagnostic, not a hard gate","typeGuard":"func isStartFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to start client\")\n}\nfunc isOAuthRequiredStart(err error) bool { return asOAuthRequired(err) != nil }","tryCatchPattern":"if err := c.Connect(ctx); err != nil {\n    if asOAuthRequired(err) != nil { return handleReauth(err) }\n    if isStartFailure(err) {\n        log.Warnf(\"MCP start failed: %v\", errors.Unwrap(err))\n        return retryWithBackoff(ctx, func() error { return c.Connect(ctx) })\n    }\n    return err\n}","preventionTips":["Health-check MCP endpoints before saving them as services","Monitor egress/DNS/TLS from the deployment environment","Distinguish OAuth-required errors from network errors and route the former to re-auth flows"],"tags":["go","mcp","network","connection","sse"],"backgroundTag":"connection-refused","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}