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

  1. Retry with backoff - the first poll may simply not have landed yet
  2. Verify the discovery server address in the client config and that the server is reachable (curl http://node/discovery/polls)
  3. Confirm the target app is registered (check the discovery console) and the app id string matches exactly
  4. 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

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


AI-assisted analysis of go-kratos/kratos@668db92c2c (2026-08-16). Data as JSON: /api/errors/3e81375ed5d07a41. Report an issue: GitHub.