googleapis/mcp-toolbox · error
unable to retrieve source %q for tool %q
Error message
unable to retrieve source %q for tool %q
What it means
After a tool initializes successfully, initializeTools looks up the tool's declared source (t.GetSourceName()) in the initialized sourcesMap. If the source name is not found and source validation is enabled (SkipSourceValidation is false), startup fails because the tool points at a source that does not exist in the config.
Source
Thrown at internal/server/server.go:295
var src sources.Source
t, err := func() (tools.Tool, error) {
_, span := instrumentation.Tracer.Start(
ctx,
"toolbox/server/tool/init",
trace.WithAttributes(attribute.String("tool_type", tc.ToolConfigType())),
trace.WithAttributes(attribute.String("tool_name", name)),
)
defer span.End()
t, err := tc.Initialize(ctx)
if err != nil {
return nil, fmt.Errorf("unable to initialize tool %q: %w", name, err)
}
if srcName := t.GetSourceName(); srcName != "" && sourcesMap != nil {
var ok bool
src, ok = sourcesMap[srcName]
if !ok && !cfg.SkipSourceValidation {
return nil, fmt.Errorf("unable to retrieve source %q for tool %q", srcName, name)
}
}
if !cfg.SkipSourceValidation {
err = t.ValidateSource(src)
if err != nil {
return nil, err
}
}
return t, nil
}()
if err != nil {
return nil, err
}
if tools.ShouldSuppress(ctx, t, src) {
continue
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- Add or fix the `source:` reference in the tool config to match an existing key under `sources:`.
- List your sources section and confirm the exact spelling/case of the key.
- If the source intentionally varies per environment, template the config (envsubst) so names stay consistent.
Example fix
// before (tools.yml)
tools:
search_users:
kind: postgres-sql
source: postgress # typo
// after
sources:
postgres:
kind: postgres
uri: ...
tools:
search_users:
kind: postgres-sql
source: postgres Defensive patterns
Strategy: validation
Validate before calling
sources := cfg.Sources // map[string]SourceConfig
for name, tc := range cfg.ToolConfigs {
if src := tc.SourceName(); src != "" {
if _, ok := sources[src]; !ok {
return fmt.Errorf("tool %q references unknown source %q", name, src)
}
}
} Type guard
func sourceExists(cfg server.ServerConfig, name string) bool {
_, ok := cfg.Sources[name]
return ok
} Try / catch
if _, err := server.NewServer(ctx, cfg); err != nil {
var src, tool string
if _, e := fmt.Sscanf(err.Error(), "unable to retrieve source %q for tool %q", &src, &tool); e == nil {
log.Printf("add or fix source %q used by tool %q", src, tool)
}
return err
} Prevention
- Keep source keys and tool `source:` references in one reviewed config file.
- Use consistent naming conventions and copy-paste the exact key.
- Add a config lint step that cross-references tool source names against defined sources.
- Remember map keys are case-sensitive.
When it happens
Trigger: A tool entry in the config declares `source: some_name` but no source with that key exists under `sources:` in tools.yml, and the server is started normally (not the offline path, which sets SkipSourceValidation=true).
Common situations: Renamed or deleted source entries while tools still reference the old name, typos in the source key (map keys are case-sensitive), or copy-pasting tools between config files whose sources differ.
Related errors
- unable to initialize logger: %w
- unable to initialize tool %q: %w
- unable to initialize configs: %w
- error setting up OpenTelemetry: %w
- unable to create telemetry instrumentation: %w
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/9e653a6458ba062e.
Report an issue: GitHub.