{"record":{"id":"4fb537e07a908bc5","repo":"grpc/grpc-go","slug":"failed-to-start-resolver-w","errorCode":null,"errorMessage":"failed to start resolver: %w","messagePattern":"failed to start resolver: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"clientconn.go","lineNumber":416,"sourceCode":"\tcc.mu.Unlock()\n\n\t// Set state to CONNECTING before building the name resolver\n\t// so the channel does not remain in IDLE.\n\tcc.csMgr.updateState(connectivity.Connecting)\n\n\t// This needs to be called without cc.mu because this builds a new resolver\n\t// which might update state or report error inline, which would then need to\n\t// acquire cc.mu.\n\tif err := cc.resolverWrapper.start(); err != nil {\n\t\t// If resolver creation fails, treat it like an error reported by the\n\t\t// resolver before any valid updates. Set channel's state to\n\t\t// TransientFailure, and set an erroring picker with the resolver build\n\t\t// error, which will returned as part of any subsequent RPCs.\n\t\tlogger.Warningf(\"Failed to start resolver: %v\", err)\n\t\tcc.csMgr.updateState(connectivity.TransientFailure)\n\t\tcc.mu.Lock()\n\t\tcc.updateResolverStateAndUnlock(resolver.State{}, err)\n\t\treturn fmt.Errorf(\"failed to start resolver: %w\", err)\n\t}\n\n\tcc.addTraceEvent(\"exiting idle mode\")\n\treturn nil\n}\n\n// initIdleStateLocked initializes common state to how it should be while idle.\nfunc (cc *ClientConn) initIdleStateLocked() {\n\tcc.resolverWrapper = newCCResolverWrapper(cc)\n\tcc.balancerWrapper = newCCBalancerWrapper(cc)\n\tcc.firstResolveEvent = grpcsync.NewEvent()\n\t// cc.conns == nil is a proxy for the ClientConn being closed. So, instead\n\t// of setting it to nil here, we recreate the map. This also means that we\n\t// don't have to do this when exiting idle mode.\n\tcc.conns = make(map[*addrConn]struct{})\n}\n\n// enterIdleMode puts the channel in idle mode, and as part of it shuts down the","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/clientconn.go#L398-L434","documentation":"exitIdleMode starts the resolver wrapper (clientconn.go:407). If resolverWrapper.start() fails, the channel is put into TRANSIENT_FAILURE and the error is wrapped as \"failed to start resolver: %w\" (clientconn.go:416). This surfaces from DialContext (eager) and from the first RPC (lazy, via NewClient).","triggerScenarios":"The resolver builder's Build returns an error; the target URL is malformed; the resolver scheme is unregistered so no builder is found; a custom resolver fails to initialize.","commonSituations":"Target string like \"foo:///host\" where \"foo\" resolver is not registered; missing import of the resolver package; invalid target URL that fails url.Parse inside the resolver; DNS resolver failing at construction in restricted environments.","solutions":["Unwrap the error to see the resolver-specific failure message.","Confirm the scheme in the target maps to a registered resolver (import its package or use a built-in like dns/passthrough).","Use grpc.NewClient and check the error from the first RPC to get the lazy, unwrapped resolver error, or switch to a known scheme."],"exampleFix":"// before\ncc, err := grpc.NewClient(\"xds:///wrong\") // xds not registered / misconfigured\n// after: register/fix scheme, or use dns\ncc, err := grpc.NewClient(\"dns:///my.backend:443\", grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})))","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"cc, err := grpc.NewClient(target, opts...)\nif err != nil { return err }\n// first RPC surfaces resolver errors lazily; alternatively call Connect()\nif err := someStub.Call(ctx, req); err != nil {\n    if strings.Contains(err.Error(), \"failed to start resolver\") { /* resolver config issue */ }\n}","preventionTips":["Register the resolver for your target scheme (import its package).","Use a well-formed target URL with a known scheme (dns, passthrough, xds, ...).","Unwrap the returned error to read the resolver-specific cause."],"tags":["go","grpc","dial","resolver","idle","config"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}