{"record":{"id":"477117fd0cb393e1","repo":"grpc/grpc-go","slug":"delegating-resolver-unable-to-build-the-resolver","errorCode":null,"errorMessage":"delegating_resolver: unable to build the resolver for target %s: %v","messagePattern":"delegating_resolver: unable to build the resolver for target (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/resolver/delegatingresolver/delegatingresolver.go","lineNumber":158,"sourceCode":"\tr.childMu.Lock()\n\tdefer r.childMu.Unlock()\n\t// When the scheme is 'dns' and target resolution on client is not enabled,\n\t// resolution should be handled by the proxy, not the client. Therefore, we\n\t// bypass the target resolver and store the unresolved target address.\n\tif target.URL.Scheme == \"dns\" && !targetResolutionEnabled {\n\t\tr.targetResolverState = &resolver.State{\n\t\t\tAddresses: []resolver.Address{{Addr: addr}},\n\t\t\tEndpoints: []resolver.Endpoint{{Addresses: []resolver.Address{{Addr: addr}}}},\n\t\t}\n\t\tr.updateTargetResolverState(*r.targetResolverState)\n\t\treturn r, nil\n\t}\n\twcc := &wrappingClientConn{\n\t\tstateListener: r.updateTargetResolverState,\n\t\tparent:        r,\n\t}\n\tif r.targetResolver, err = targetResolverBuilder.Build(target, wcc, opts); err != nil {\n\t\treturn nil, fmt.Errorf(\"delegating_resolver: unable to build the resolver for target %s: %v\", target, err)\n\t}\n\treturn r, nil\n}\n\n// proxyURIResolver creates a resolver for resolving proxy URIs using the \"dns\"\n// scheme. It adjusts the proxyURL to conform to the \"dns:///\" format and builds\n// a resolver with a wrappingClientConn to capture resolved addresses.\nfunc (r *delegatingResolver) proxyURIResolver(opts resolver.BuildOptions) (resolver.Resolver, error) {\n\tproxyBuilder := resolver.Get(\"dns\")\n\tif proxyBuilder == nil {\n\t\tpanic(\"delegating_resolver: resolver for proxy not found for scheme dns\")\n\t}\n\turl := *r.proxyURL\n\turl.Scheme = \"dns\"\n\turl.Path = \"/\" + r.proxyURL.Host\n\turl.Host = \"\" // Clear the Host field to conform to the \"dns:///\" format\n\n\tproxyTarget := resolver.Target{URL: url}","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/resolver/delegatingresolver/delegatingresolver.go#L140-L176","documentation":"Returned by New() when targetResolverBuilder.Build(target, wcc, opts) fails while constructing the child target resolver (with a proxy active and target resolution enabled). The wrapped error comes from the underlying resolver builder (typically dns or a custom resolver registered via WithResolvers). The whole delegating resolver construction fails.","triggerScenarios":"The dns resolver builder rejecting the target (bad host/port), a custom resolver builder returning an error from Build, or no resolver registered for the target's scheme.","commonSituations":"Dial target uses an unregistered scheme; custom resolver builder misconfigured via WithResolvers; dns authority portion of the URI unresolvable; version change that altered how schemes are resolved.","solutions":["Inspect the wrapped error to see which builder failed and why.","Ensure a resolver is registered for the target scheme (dns is default; register custom schemes via resolver.Register).","For dns, verify the target endpoint is a valid host (optionally :port).","Pass the right resolver mapping through grpc.WithResolvers for custom schemes."],"exampleFix":"// before\nresolver.Register(myBuilder) // registered after Dial\nconn, _ := grpc.Dial(\"myscheme:///svc\", ...)\n// after\nresolver.Register(myBuilder) // register BEFORE Dial\nconn, _ := grpc.Dial(\"myscheme:///svc\", grpc.WithResolvers(myBuilder))","handlingStrategy":"try-catch","validationCode":"// Ensure a resolver exists for the scheme before dialing.\nfunc schemeRegistered(s string) bool {\n    return resolver.Get(s) != nil\n}","typeGuard":null,"tryCatchPattern":"conn, err := grpc.Dial(target, ...)\nif err != nil && strings.Contains(err.Error(), \"unable to build the resolver\") {\n    // Fall back to the default dns resolver form.\n    conn, err = grpc.Dial(\"dns:///\"+hostPort, ...)\n}","preventionTips":["Register custom resolver builders in init() before any Dial.","Pass grpc.WithResolvers(builder) for custom schemes.","Default to dns:/// targets when no custom scheme is required."],"tags":["grpc","resolver","delegating-resolver","dns","custom-scheme","initialization"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}