grpc/grpc-go · error

delegating_resolver: invalid target address %q: %v

Error message

delegating_resolver: invalid target address %q: %v

What it means

Returned by the delegating resolver's New() when, for a dns-scheme target with target resolution disabled and EnableDefaultPortForProxyTarget set, parseTarget(addr) fails. parseTarget rejects empty addresses and addresses ending in a colon with no port. The error is returned from resolver construction and surfaces as a dial failure.

Source

Thrown at internal/resolver/delegatingresolver/delegatingresolver.go:119

//     in the target URI or specified by the user using the WithResolvers dial
//     option. As a special case, if the target URI's scheme is "dns" and a
//     proxy is specified using the supported environment variables, the target
//     URI's path portion is used as the resolved address unless target
//     resolution is enabled using the dial option.
func New(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions, targetResolverBuilder resolver.Builder, targetResolutionEnabled bool) (resolver.Resolver, error) {
	r := &delegatingResolver{
		target:         target,
		cc:             cc,
		proxyResolver:  nopResolver{},
		targetResolver: nopResolver{},
	}

	addr := target.Endpoint()
	var err error
	if target.URL.Scheme == "dns" && !targetResolutionEnabled && envconfig.EnableDefaultPortForProxyTarget {
		addr, err = parseTarget(addr)
		if err != nil {
			return nil, fmt.Errorf("delegating_resolver: invalid target address %q: %v", target.Endpoint(), err)
		}
	}

	r.proxyURL, err = proxyURLForTarget(addr)
	if err != nil {
		return nil, fmt.Errorf("delegating_resolver: failed to determine proxy URL for target %q: %v", target, err)
	}

	// proxy is not configured or proxy address excluded using `NO_PROXY` env
	// var, so only target resolver is used.
	if r.proxyURL == nil {
		return targetResolverBuilder.Build(target, cc, opts)
	}

	if logger.V(2) {
		logger.Infof("Proxy URL detected : %s", r.proxyURL)
	}

View on GitHub (pinned to 03255a9237)

Solutions

  1. Provide a non-empty host (and a valid port or no port) in the target: "dns:///host:443" or "dns:///host".
  2. Audit the code that assembles the target URI to avoid trailing colons or empty endpoints.
  3. Disable the EnableDefaultPortForProxyTarget experiment if it is not needed.

Example fix

// before
conn, _ := grpc.Dial("dns:///:", ...) // -> invalid target address
// after
conn, _ := grpc.Dial("dns:///my-service:443", ...)
Defensive patterns

Strategy: validation

Validate before calling

// Validate the target endpoint before dialing.
func validTarget(t string) error {
    ep := strings.TrimPrefix(t, "dns:///")
    if ep == "" || strings.HasSuffix(ep, ":") {
        return fmt.Errorf("bad target %q", t)
    }
    return nil
}

Try / catch

conn, err := grpc.Dial(target, ...)
if err != nil {
    if strings.Contains(err.Error(), "invalid target address") {
        return fmt.Errorf("fix target URI %q: %w", target, err)
    }
}

Prevention

When it happens

Trigger: Dialing a dns:/// target whose endpoint is empty or malformed (e.g. "dns:///:", "dns:///host:") while a proxy is configured via HTTPS_PROXY and the feature flag EnableDefaultPortForProxyTarget is on.

Common situations: Constructing the dial target string dynamically and leaving the host blank; trailing colon from string concatenation; misconfigured target builder that drops the host portion.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/3dc017133a91d408. Report an issue: GitHub.