{"record":{"id":"9fb4c429a54d89ec","repo":"grpc/grpc-go","slug":"grpc-timed-out-when-dialing","errorCode":null,"errorMessage":"grpc: timed out when dialing","messagePattern":"grpc: timed out when dialing","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"clientconn.go","lineNumber":1789,"sourceCode":"func (ac *addrConn) incrCallsStarted() {\n\tac.channelz.ChannelMetrics.CallsStarted.Add(1)\n\tac.channelz.ChannelMetrics.LastCallStartedTimestamp.Store(time.Now().UnixNano())\n}\n\nfunc (ac *addrConn) incrCallsSucceeded() {\n\tac.channelz.ChannelMetrics.CallsSucceeded.Add(1)\n}\n\nfunc (ac *addrConn) incrCallsFailed() {\n\tac.channelz.ChannelMetrics.CallsFailed.Add(1)\n}\n\n// ErrClientConnTimeout indicates that the ClientConn cannot establish the\n// underlying connections within the specified timeout.\n//\n// Deprecated: This error is never returned by grpc and should not be\n// referenced by users.\nvar ErrClientConnTimeout = errors.New(\"grpc: timed out when dialing\")\n\n// getResolver finds the scheme in the cc's resolvers or the global registry.\n// scheme should always be lowercase (typically by virtue of url.Parse()\n// performing proper RFC3986 behavior).\nfunc (cc *ClientConn) getResolver(scheme string) resolver.Builder {\n\tfor _, rb := range cc.dopts.resolvers {\n\t\tif scheme == rb.Scheme() {\n\t\t\treturn rb\n\t\t}\n\t}\n\treturn resolver.Get(scheme)\n}\n\nfunc (cc *ClientConn) updateConnectionError(err error) {\n\tcc.lceMu.Lock()\n\tcc.lastConnectionError = err\n\tcc.lceMu.Unlock()\n}","sourceCodeStart":1771,"sourceCodeEnd":1807,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/clientconn.go#L1771-L1807","documentation":"ErrClientConnTimeout (clientconn.go:1784-1789) is a DEPRECATED exported sentinel whose doc comment states plainly: 'This error is never returned by grpc and should not be referenced by users.' Modern grpc-go surfaces dial timeouts as context.DeadlineExceeded (from the dial context) wrapped in a status with code Unavailable.","triggerScenarios":"Historically meant to indicate the connection could not be established within the timeout. In current grpc-go nothing returns it; the only way a user sees it is by importing and comparing against it themselves. Real dial timeouts come through as the context error / a status.Unavailable wrapping the underlying connection error.","commonSituations":"Legacy code that does if err == grpc.ErrClientConnTimeout; copying old examples; static analysis flagging the symbol; grepping for timeout handling.","solutions":["Stop comparing against ErrClientConnTimeout — it is never produced by the library.","Detect dial timeout via the error returned from DialContext/Invoke: check status.Code(err)==codes.Unavailable and/or errors.Is(err, context.DeadlineExceeded).","Use grpc.WithTimeout (deprecated) or, preferably, a context.WithTimeout passed to the call to bound dial/RPC time.","Inspect connectionError() / the wrapped cause for the real TCP/TLS failure underneath the timeout."],"exampleFix":"// before — deprecated, never matches\nif err == grpc.ErrClientConnTimeout { ... }\n\n// after — use status + context\nst, ok := status.FromError(err)\nif ok && st.Code() == codes.Unavailable && errors.Is(err, context.DeadlineExceeded) {\n    // dial/RPC timed out\n}","handlingStrategy":"try-catch","validationCode":"// Do NOT reference ErrClientConnTimeout; detect timeouts via status+context\nfunc isDialTimeout(err error) bool {\n    return status.Code(err) == codes.Unavailable && errors.Is(err, context.DeadlineExceeded)\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, context.DeadlineExceeded) || status.Code(err) == codes.Unavailable {\n    // dial/RPC timed out; ErrClientConnTimeout is never returned by grpc\n}","preventionTips":["Remove any `err == grpc.ErrClientConnTimeout` checks; it never matches.","Bound dial time with context.WithTimeout on the call.","Inspect wrapped errors via errors.Is rather than equality."],"tags":["deprecated","timeout","dial","grpc-go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}