{"record":{"id":"ef1772e20a9c89b1","repo":"grpc/grpc-go","slug":"bad-resolver-state","errorCode":null,"errorMessage":"bad resolver state","messagePattern":"bad resolver state","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/balancer.go","lineNumber":394,"sourceCode":"type ExitIdler interface {\n\t// ExitIdle instructs the LB policy to reconnect to backends / exit the\n\t// IDLE state, if appropriate and possible.  Note that SubConns that enter\n\t// the IDLE state will not reconnect until SubConn.Connect is called.\n\tExitIdle()\n}\n\n// ClientConnState describes the state of a ClientConn relevant to the\n// balancer.\ntype ClientConnState struct {\n\tResolverState resolver.State\n\t// The parsed load balancing configuration returned by the builder's\n\t// ParseConfig method, if implemented.\n\tBalancerConfig serviceconfig.LoadBalancingConfig\n}\n\n// ErrBadResolverState may be returned by UpdateClientConnState to indicate a\n// problem with the provided name resolver data.\nvar ErrBadResolverState = errors.New(\"bad resolver state\")\n","sourceCodeStart":376,"sourceCodeEnd":395,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/balancer/balancer.go#L376-L395","documentation":"balancer.ErrBadResolverState is the sentinel a Balancer returns from UpdateClientConnState to flag that the resolver produced unusable data. Per balancer/balancer.go:345-350, when this is returned the ClientConn starts calling ResolveNow on the active resolver with exponential backoff until a subsequent UpdateClientConnState returns nil. Other returned errors are currently ignored, so this sentinel is the ONLY way to request a re-resolution.","triggerScenarios":"A Balancer.UpdateClientConnState returns ErrBadResolverState — most often because ClientConnState.ResolverState has no addresses, the service config failed to parse in the balancer's ParseConfig, or the addresses/endpoints are malformed for that policy (e.g. endpointsharding/weightedtarget receiving zero endpoints).","commonSituations":"A service config JSON typo that makes ParseConfig fail; resolver returning an empty address list (DNS returns nothing, xDS has no hosts); custom balancer that treats missing required metadata as fatal; bootstrap/misconfigured authority yielding no endpoints.","solutions":["Check the resolver output: log ResolverState.Addresses and ResolverState.Endpoints — an empty set means upstream resolution is broken (DNS, xDS, custom resolver).","Validate the service config: if the policy has a ParseConfig, ensure the JSON/YAML matches its schema; fix the config in the control plane.","If you author a balancer, return ErrBadResolverState ONLY for genuinely unrecoverable resolver data so gRPC will back off and re-resolve.","Verify the dial target scheme/authority is correct (e.g. dns:///<service>, xds:///<resource>)."],"exampleFix":"// before — balancer silently fails, no re-resolution\nfunc (b *lb) UpdateClientConnState(s balancer.ClientConnState) error {\n    return fmt.Errorf(\"no addresses\")\n}\n\n// after — request backoff re-resolution\nfunc (b *lb) UpdateClientConnState(s balancer.ClientConnState) error {\n    if len(s.ResolverState.Addresses) == 0 && s.ResolverState.Endpoints == nil {\n        return balancer.ErrBadResolverState\n    }\n    ...\n}","handlingStrategy":"retry","validationCode":"// Validate resolver state before your balancer acts on it\nfunc (b *lb) UpdateClientConnState(s balancer.ClientConnState) error {\n    if len(s.ResolverState.Addresses) == 0 && len(s.ResolverState.Endpoints) == 0 {\n        return balancer.ErrBadResolverState // triggers backoff re-resolution\n    }\n    return b.apply(s)\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, balancer.ErrBadResolverState) {\n    // gRPC is already backing off and re-resolving; surface as Unavailable to caller\n}","preventionTips":["Return ErrBadResolverState ONLY for unrecoverable resolver data so backoff kicks in.","Validate service config JSON in ParseConfig before applying.","Log resolver.State contents when re-resolution loops persist."],"tags":["resolver","balancer","service-config","grpc-go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}