grpc/grpc-go · error
dns resolver: missing address
Error message
dns resolver: missing address
What it means
ErrMissingAddr (internal/resolver/dns/internal/internal.go:41) is the sentinel returned by the dns resolver builder when the target name passed in is empty. The dns resolver needs a host name to resolve; with an empty endpoint there is nothing to look up, so the resolver build fails immediately. Exported as a package var so callers can errors.Is-match it.
Source
Thrown at internal/resolver/dns/internal/internal.go:41
"context"
"errors"
"net"
"time"
)
// NetResolver groups the methods on net.Resolver that are used by the DNS
// resolver implementation. This allows the default net.Resolver instance to be
// overridden from tests.
type NetResolver interface {
LookupHost(ctx context.Context, host string) (addrs []string, err error)
LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error)
LookupTXT(ctx context.Context, name string) (txts []string, err error)
}
var (
// ErrMissingAddr is the error returned when building a DNS resolver when
// the provided target name is empty.
ErrMissingAddr = errors.New("dns resolver: missing address")
// ErrEndsWithColon is the error returned when building a DNS resolver when
// the provided target name ends with a colon that is supposed to be the
// separator between host and port. E.g. "::" is a valid address as it is
// an IPv6 address (host only) and "[::]:" is invalid as it ends with a
// colon as the host and port separator
ErrEndsWithColon = errors.New("dns resolver: missing port after port-separator colon")
)
// The following vars are overridden from tests.
var (
// TimeAfterFunc is used by the DNS resolver to wait for the given duration
// to elapse. In non-test code, this is implemented by time.After. In test
// code, this can be used to control the amount of time the resolver is
// blocked waiting for the duration to elapse.
TimeAfterFunc func(time.Duration) <-chan time.Time
// TimeNowFunc is used by the DNS resolver to get the current time.View on GitHub (pinned to 03255a9237)
Solutions
- Provide a non-empty host in the dns:// target, e.g. grpc.Dial("dns:///service.example.com:443", ...).
- Validate the resolved host string is non-empty before constructing the target.
- Check for this specific error with errors.Is(err, internal.ErrMissingAddr) (or the resolver's typed error) to give a clearer startup message.
Example fix
// before
host := os.Getenv("BACKEND_HOST") // ""
conn, _ := grpc.Dial(fmt.Sprintf("dns:///%s:443", host), ...) // err: missing address
// after
host := os.Getenv("BACKEND_HOST")
if host == "" { log.Fatal("BACKEND_HOST not set") }
conn, _ := grpc.Dial(fmt.Sprintf("dns:///%s:443", host), ...) Defensive patterns
Strategy: validation
Validate before calling
host := strings.TrimSpace(targetHost)
if host == "" {
return errors.New("dns target host is empty")
}
dialTarget := fmt.Sprintf("dns:///%s", host) Try / catch
conn, err := grpc.Dial(target, ...)
if err != nil {
if errors.Is(err, internal.ErrMissingAddr) {
log.Fatal("dial target is empty; set the backend host")
}
log.Fatal(err)
} Prevention
- Validate the resolved host is non-empty before building the dns:// target.
- Guard env-var-backed hosts with a non-empty check at startup.
When it happens
Trigger: Dialing with a dns:// target whose authority/endpoint is empty, e.g. grpc.Dial("dns:///") or a programmatically-built target where Endpoint() returns "". The resolver Build() detects the empty endpoint and returns ErrMissingAddr, causing Dial to fail.
Common situations: Building a target string via fmt.Sprintf with an empty host var; dropping the host part while keeping the dns:// scheme; env var holding the backend host being unset so the dial target becomes dns:///:443; mis-parsed service discovery URL.
Related errors
- dns resolver: missing port after port-separator colon
- passthrough: received empty target in Build()
- empty token_exchange_service_uri in options
- required field SubjectTokenPath is not specified
- required field SubjectTokenType is not specified
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/8814e66c484bac82.
Report an issue: GitHub.