micro/go-micro · error
registry is required
Error message
registry is required
What it means
NewServer validates its Options before constructing the MCP gateway Server. Since the gateway relies entirely on the registry for service discovery and tool building, a nil Registry makes the server unusable, so construction fails immediately with "registry is required" instead of panicking later.
Source
Thrown at gateway/mcp/mcp.go:266
// NewServer creates an MCP gateway server from opts and starts service
// discovery and registry watching. It does not begin serving; call
// (*Server).Serve to start a transport and (*Server).Stop to shut down
// gracefully. This lets callers (e.g. the micro CLI) orchestrate the MCP
// gateway independently of any other gateway.
func NewServer(opts Options) (*Server, error) {
// Set defaults
if opts.Client == nil {
opts.Client = client.DefaultClient
}
if opts.Context == nil {
opts.Context = context.Background()
}
if opts.Logger == nil {
opts.Logger = log.Default()
}
if opts.Registry == nil {
return nil, fmt.Errorf("registry is required")
}
server := &Server{
opts: opts,
tools: make(map[string]*Tool),
limiters: make(map[string]*rateLimiter),
breakers: make(map[string]*circuitBreaker),
}
// Discover services and build tool list
if err := server.discoverServices(); err != nil {
return nil, fmt.Errorf("failed to discover services: %w", err)
}
// Watch for service changes
go server.watchServices()
return server, nilView on GitHub (pinned to 24529f1404)
Solutions
- Set Options.Registry to a registry implementation, e.g. Registry: service.Options().Registry or Registry: registry.DefaultRegistry.
- If no service exists, explicitly construct one: reg := registry.NewRegistry(), then pass it in Options.
- For tests, pass a memory registry such as memory.NewRegistry().
Example fix
// before
srv, err := mcp.NewServer(mcp.Options{Address: ":3000"})
// after
srv, err := mcp.NewServer(mcp.Options{
Registry: service.Options().Registry,
Address: ":3000",
}) Defensive patterns
Strategy: validation
Validate before calling
if opts.Registry == nil {
return fmt.Errorf("mcp.Options.Registry must be set before calling NewServer")
} Try / catch
srv, err := mcp.NewServer(opts)
if err != nil {
log.Fatalf("mcp server init failed: %v", err)
} Prevention
- Always set Options.Registry from an initialized micro service (service.Options().Registry).
- Centralize MCP Options construction in one helper so Registry can never be forgotten.
- Add a unit test asserting NewServer succeeds with your production Options.
When it happens
Trigger: Calling mcp.NewServer (directly or via mcp.Serve/Run) with an Options struct where the Registry field is left as its zero value (nil), e.g. mcp.NewServer(mcp.Options{Address: ":3000"}) without setting Registry.
Common situations: Developers copy the doc example but forget to pass service.Options().Registry; constructing Options programmatically in tests; running the gateway in a binary that never initialized a go-micro service so no registry was available to pass.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- no registry configured
- no service name configured
- failed to discover services: %w
- agent: ResumeStreamAsk requires a checkpoint
- ai model is nil
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/f7d8c5086975fc0b.
Report an issue: GitHub.