vitessio/vitess · error
failed to discover %ss (cluster %s): %w
Error message
failed to discover %ss (cluster %s): %w
What it means
resolver.resolve runs address discovery for the target component (vtctld or vtgate) under r.opts.DiscoveryTimeout and wraps any discovery failure with the component and cluster name. It means the underlying discovery mechanism (e.g. topology service lookups via DiscoverVtctldAddrs/DiscoverVTGateAddrs) returned an error or found no addresses, so the resolver cannot produce a gRPC address list.
Source
Thrown at go/vt/vtadmin/cluster/resolver/resolver.go:435
}
}
}
func (r *resolver) resolve() (*grpcresolver.State, error) {
span, ctx := trace.NewSpan(r.ctx, "(vtadmin/cluster/resolver).resolve")
defer span.Finish()
span.Annotate("cluster_id", r.cluster)
span.Annotate("component", r.component)
log.Info(fmt.Sprintf("%s: resolving %ss (cluster %s)", logPrefix, r.component, r.cluster))
ctx, cancel := context.WithTimeout(ctx, r.opts.DiscoveryTimeout)
defer cancel()
addrs, err := r.discoverAddrs(ctx, r.opts.DiscoveryTags)
if err != nil {
return nil, fmt.Errorf("failed to discover %ss (cluster %s): %w", r.component, r.cluster, err)
}
span.Annotate("addrs", strings.Join(addrs, ","))
state := &grpcresolver.State{
Addresses: make([]grpcresolver.Address, len(addrs)),
}
if r.sc != nil {
span.Annotate("balancer_policy", r.opts.BalancerPolicy)
state.ServiceConfig = &serviceconfig.ParseResult{
Config: r.sc,
}
}
for i, addr := range addrs {
state.Addresses[i] = grpcresolver.Address{
Addr: addr,View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the wrapped error: timeout vs topo connection failure vs zero results.
- Verify vtctld/vtgate tablets are registered and healthy in the topology.
- Increase opts.DiscoveryTimeout and re-check DiscoveryTags for correctness.
- Confirm network connectivity and topo credentials from the vtadmin host.
- gRPC will retry resolve; fix the underlying discovery and let the resolver re-resolve.
Example fix
// before
opts := resolver.Options{DiscoveryTimeout: 100 * time.Millisecond}
// after
opts := resolver.Options{DiscoveryTimeout: 5 * time.Second} Defensive patterns
Strategy: retry
Validate before calling
addrs, err := r.discoverAddrs(ctx, r.opts.DiscoveryTags)
if err != nil || len(addrs) == 0 {
return fmt.Errorf("pre-flight discovery found no %s instances", component)
} Try / catch
err := retry.Do(func() error {
cc, err := grpc.DialContext(ctx, target,
grpc.WithResolvers(builder),
grpc.WithDefaultCallOptions(...))
if err != nil && strings.Contains(err.Error(), "failed to discover") {
return retry.RetryableError(err)
}
return err
}, retry.Attempts(5), retry.Delay(2*time.Second)) Prevention
- Ensure vtctld/vtgate are registered in the topology before pointing vtadmin at the cluster.
- Set a generous DiscoveryTimeout (seconds, not milliseconds).
- Verify DiscoveryTags actually match instance tags; empty results surface as discovery failure.
- Monitor topo service reachability from vtadmin hosts.
When it happens
Trigger: resolve() called (via the resolver's anonymous watcher) when: discovery times out (DiscoveryTimeout exceeded), the topology service is unreachable, no healthy instances match DiscoveryTags, or discoverAddrs returns an error.
Common situations: vtctld/vtgate not registered in the topology; network partitions between vtadmin and the topo servers; overly tight DiscoveryTimeout in slow clusters; wrong discovery tags configured so zero addresses match.
Related errors
- gRPC connection wait time exceeded
- FindTablets(cluster = %s): %w
- DiscoverVTGates(cluster = %s): %w
- invalid choice for enum
- parse error
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/ae6808621a0f741f.
Report an issue: GitHub.