googleapis/mcp-toolbox · critical
toolbox failed to start listener: %w
Error message
toolbox failed to start listener: %w
What it means
In runServe's non-TLS path, the server calls s.Listen(ctx, certFile, keyFile) to bind the address and serve. If the listener cannot start (port in use, permission denied, bad address), the error is wrapped with this message.
Source
Thrown at cmd/internal/serve/command.go:101
protocol := "http"
if useTLS {
protocol = "https"
}
// run server in background
srvErr := make(chan error, 1)
if opts.Cfg.Stdio {
go func() {
defer close(srvErr)
err = s.ServeStdio(ctx, opts.IOStreams.In, opts.IOStreams.Out)
if err != nil {
srvErr <- err
}
}()
} else {
err = s.Listen(ctx, opts.Cfg.CertFile, opts.Cfg.KeyFile)
if err != nil {
errMsg := fmt.Errorf("toolbox failed to start listener: %w", err)
opts.Logger.ErrorContext(ctx, errMsg.Error())
return errMsg
}
opts.Logger.InfoContext(ctx, "Server ready to serve!")
if opts.Cfg.UI {
opts.Logger.InfoContext(ctx, fmt.Sprintf("Toolbox UI is up and running at: %s://%s:%d/ui", protocol, opts.Cfg.Address, opts.Cfg.Port))
}
go func() {
defer close(srvErr)
err = s.Serve(ctx)
if err != nil {
srvErr <- err
}
}()
}
// wait for either the server to error out or the command's context to be canceledView on GitHub (pinned to 8cc6e09de2)
Solutions
- Check for a process already bound to the port (lsof -i :5000) and stop it or change --port
- Choose an unprivileged port (>1024) if not running as root
- Verify the --address value resolves to a valid local interface
- Check container/K8s port mappings and security policies
Example fix
// before ./toolbox serve --port 80 // privileged // after ./toolbox serve --port 5000
Defensive patterns
Strategy: validation
Validate before calling
// check the port is free before launching
if l, err := net.Listen("tcp", ":5000"); err != nil {
log.Fatal("port 5000 already in use")
} else { l.Close() } Try / catch
err = s.Listen(ctx, cfg.CertFile, cfg.KeyFile)
if err != nil {
return fmt.Errorf("toolbox failed to start listener: %w", err)
} Prevention
- Pick ports >1024 and make them configurable per environment
- Check for stale processes holding the port before restart
- Verify container port mappings and host networking settings
When it happens
Trigger: s.Listen returns an error: the configured address:port is already bound, the port is privileged (<1024) without permissions, or the address is invalid/unavailable.
Common situations: Another toolbox instance or service already listening on 5000 (the default port), running in a container without port mapping, or binding to an interface that doesn't exist.
Related errors
- toolbox failed to initialize: %w
- toolbox crashed with the following error: %w
- graceful shutdown timed out... forcing exit
- unable to validate reloaded edits: %w
- unable to initialize reloaded configs: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/061769940642da39.
Report an issue: GitHub.