grpc/grpc-go · error

passthrough: received empty target in Build()

Error message

passthrough: received empty target in Build()

What it means

Returned by the passthrough resolver's Build method when target.Endpoint() is empty and no custom dialer is set. The passthrough resolver simply passes the target endpoint as the resolved address; if the endpoint is empty there is nothing to connect to, and without a custom dialer there is no way to handle the emptiness. This is the fallback resolver used when no scheme-specific resolver matches.

Solutions

  1. Provide a non-empty endpoint in the dial target, e.g., grpc.Dial("passthrough:///10.0.0.1:8080").
  2. Validate the address string is non-empty before calling grpc.Dial.
  3. If using a custom dialer that resolves the address itself, pass it via grpc.WithContextDialer (the error is suppressed when opts.Dialer != nil).
  4. Log the target before dialing to catch empty values.

Example fix

// before
conn, err := grpc.Dial("") // empty target
// after
conn, err := grpc.Dial("passthrough:///10.0.0.1:8080")

// or if using a custom dialer:
conn, err := grpc.Dial("",
    grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
        return net.Dial("tcp", "10.0.0.1:8080")
    }),
)
Defensive patterns

Strategy: validation

Validate before calling

// Validate the target endpoint is non-empty before dialing.
target := strings.TrimSpace(addr)
if target == "" {
    return fmt.Errorf("dial target is empty")
}
conn, err := grpc.Dial(target)

Prevention

When it happens

Trigger: grpc.Dial with an empty target ("") or a target that reduces to an empty endpoint after parsing (e.g., "passthrough:///" with nothing after the authority), when no custom dialer (grpc.WithContextDialer) is configured. The check at passthrough.go:34-35 fires.

Common situations: Unset or empty address configuration; target string that is only a scheme with no endpoint; dial target computed from a broken template or missing environment variable; the passthrough scheme used explicitly with an empty address.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/6c83f8a942fc5075. Report an issue: GitHub.

Appendix: source

Thrown at internal/resolver/passthrough/passthrough.go:35

 */

// Package passthrough implements a pass-through resolver. It sends the target
// name without scheme back to gRPC as resolved address.
package passthrough

import (
	"errors"

	"google.golang.org/grpc/resolver"
)

const scheme = "passthrough"

type passthroughBuilder struct{}

func (*passthroughBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
	if target.Endpoint() == "" && opts.Dialer == nil {
		return nil, errors.New("passthrough: received empty target in Build()")
	}
	r := &passthroughResolver{
		target: target,
		cc:     cc,
	}
	r.start()
	return r, nil
}

func (*passthroughBuilder) Scheme() string {
	return scheme
}

type passthroughResolver struct {
	target resolver.Target
	cc     resolver.ClientConn
}

View on GitHub (pinned to 0c51461d27)