grpc/grpc-go · warning
endpoints list contains no addresses
Error message
endpoints list contains no addresses
What it means
Returned by resolver.ValidateEndpoints when the endpoints slice is non-empty but every Endpoint in it has an empty Addresses slice. The dual-stack/petiole logic needs at least one dialable address; endpoints with no addresses are not usable and the validation fails.
Solutions
- Ensure each Endpoint has at least one Address (host:port) before calling ValidateEndpoints; filter out address-less endpoints upstream.
- Check the resolver producing the Endpoint list: confirm it copies socket_addresses into Endpoint.Addresses.
- If the source genuinely has no addresses yet (e.g. DNS returned CNAME only), surface a transient error rather than a finalized empty-address list.
Example fix
// before
eps := []resolver.Endpoint{ {HealthStatus: ...} } // Addresses nil
resolver.ValidateEndpoints(eps)
// after
eps := []resolver.Endpoint{ { Addresses: []resolver.Address{{Addr: "10.0.0.1:8080"}} } }
resolver.ValidateEndpoints(eps) Defensive patterns
Strategy: validation
Validate before calling
// Filter out address-less endpoints before validation.
func withAddressesOnly(eps []resolver.Endpoint) []resolver.Endpoint {
out := eps[:0]
for _, e := range eps { if len(e.Addresses) > 0 { out = append(out, e) } }
return out
} Type guard
func endpointsHaveAddresses(eps []resolver.Endpoint) bool {
for _, e := range eps { if len(e.Addresses) > 0 { return true } }
return false
} Try / catch
if err := resolver.ValidateEndpoints(eps); err != nil { if strings.Contains(err.Error(), "no addresses") { /* keep previous picker; log transient */ return } return err } Prevention
- In resolver implementations, drop endpoints with empty Addresses before producing the update.
- Validate proto-to-resolver.Endpoint conversion covers the socket_addresses field.
- Add test coverage for EDS responses with localities but no endpoints.
When it happens
Trigger: Calling ValidateEndpoints with a list of Endpoint structs whose Addresses field is nil or [] for all entries. Each iteration of the inner loop `for range endpoint.Addresses` returns immediately, so the function falls through to the error.
Common situations: EDS/xDS update carries localities but each locality's endpoints were stripped of addresses by a buggy filter. Custom resolver populates metadata but not Addresses. A proto conversion dropped the address field during a version upgrade.
Related errors
- endpoints list is empty
- connection active but health check failed. status=
- connection active but received health check RPC error
- could not get resolver for default scheme
- delegating_resolver: failed to determine proxy URL for…
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/e88afdba4166bebe.
Report an issue: GitHub.
Appendix: source
Thrown at resolver/resolver.go:358
// necessary.
OverrideAuthority(Target) string
}
// ValidateEndpoints validates endpoints from a petiole policy's perspective.
// Petiole policies should call this before calling into their children. See
// [gRPC A61](https://github.com/grpc/proposal/blob/master/A61-IPv4-IPv6-dualstack-backends.md)
// for details.
func ValidateEndpoints(endpoints []Endpoint) error {
if len(endpoints) == 0 {
return errors.New("endpoints list is empty")
}
for _, endpoint := range endpoints {
for range endpoint.Addresses {
return nil
}
}
return errors.New("endpoints list contains no addresses")
}
View on GitHub (pinned to 0c51461d27)