go-kratos/kratos · error
Discovery.GetService fetch failed
Error message
Discovery.GetService fetch failed
What it means
Returned by Discovery.GetService (contrib/registry/discovery/impl_discover.go:34) when r.fetch(ctx) reports ok=false. Looking at Resolve.fetch (discovery.go:421), ok is false when the app id is absent from the client's cached d.apps map or the zoneIns slot holds a non-disInstancesInfo value - i.e. the background poller has never successfully fetched this app from the discovery server. So the root cause is almost always upstream: the polls long-connection failed, the server is unreachable, or the app was never registered. The ctx argument is ignored by fetch, so cancelling the context does not produce this error.
Source
Thrown at contrib/registry/discovery/impl_discover.go:34
return nil
}
out := make([]*registry.ServiceInstance, 0, len(zoneInstance))
for _, v := range zoneInstance {
if v == nil {
continue
}
out = append(out, toServiceInstance(v))
}
return out
}
func (d *Discovery) GetService(ctx context.Context, serviceName string) ([]*registry.ServiceInstance, error) {
r := d.resolveBuild(serviceName)
ins, ok := r.fetch(ctx)
if !ok {
return nil, errors.New("Discovery.GetService fetch failed")
}
out := filterInstancesByZone(ins, d.config.Zone)
if len(out) == 0 {
return nil, fmt.Errorf("Discovery.GetService(%s) not found", serviceName)
}
return out, nil
}
func (d *Discovery) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) {
return &watcher{
resolve: d.resolveBuild(serviceName),
serviceName: serviceName,
cancelCtx: ctx,
}, nil
}
View on GitHub (pinned to 668db92c2c)
Solutions
- Retry with backoff - the first poll may simply not have landed yet
- Verify the discovery server address in the client config and that the server is reachable (curl http://node/discovery/polls)
- Confirm the target app is registered (check the discovery console) and the app id string matches exactly
- Check the client logs for 'Discovery: polls failed' style errors which indicate the background fetch is failing
Example fix
// before
ins, err := d.GetService(ctx, "user.service")
if err != nil { return err } // fetch failed on cold start
// after
var ins []*registry.ServiceInstance
for attempt := 0; attempt < 5; attempt++ {
ins, err = d.GetService(ctx, "user.service")
if err == nil { break }
time.Sleep(time.Duration(attempt+1) * 200 * time.Millisecond)
} Defensive patterns
Strategy: retry
Try / catch
var ins []*registry.ServiceInstance
err := backoff.Retry(func() error {
var e error
ins, e = d.GetService(ctx, "user.service")
return e // retry while fetch fails / cache cold
}, backoff.WithMaxRetries(5)) Prevention
- Expect cold-start misses: build retry-with-backoff around initial GetService calls
- Health-check the discovery server endpoint before declaring an app missing
- Distinguish the two failures: 'fetch failed' = cache/poller problem, 'not found' = zone or registration problem
- Confirm d.config.Zone matches instances' registered zones or leave it empty
When it happens
Trigger: d.GetService(ctx, "user.service") before the first successful poll completes; discovery server down or the configured nodes unreachable so d.apps never populates; app id typo so no such app exists server-side (distinguish from the zone-empty case which yields 'Discovery.GetService(x) not found' instead); client just started and the poll goroutine has not finished its first request.
Common situations: Startup race where GetService is called immediately after creating the Discovery client; discovery node address misconfigured; network partition between the app and the discovery server; the target service crashed and its registration expired server-side.
Related errors
- ErrorCode: %d
- register failed: instance duplicated:
- discovery create watcher overtime
- iterator closed
- kratos/nacos: ServiceInstance.Name can not be empty
AI-assisted analysis of go-kratos/kratos@668db92c2c (2026-08-16).
Data as JSON: /api/errors/3e81375ed5d07a41.
Report an issue: GitHub.