googleapis/mcp-toolbox · error

elasticsearch source %q requires either username/password or

Error message

elasticsearch source %q requires either username/password or an API key

What it means

Thrown by Config.Initialize when an elasticsearch source defines neither a username+password pair nor an API key. The Elasticsearch client requires one of these credential mechanisms for authentication, so the toolbox refuses to initialize the source rather than creating a client that would fail on every request.

Source

Thrown at internal/sources/elasticsearch/elasticsearch.go:113

	}

	// Create a new Elasticsearch client with the provided configuration
	cfg := elasticsearch.Config{
		Addresses:       c.Addresses,
		Instrumentation: elasticsearch.NewOpenTelemetryInstrumentation(tracerProvider, false),
		Header:          http.Header{"User-Agent": []string{ua + " go-elasticsearch/" + elasticsearch.Version}},
	}

	// Client need either username and password or an API key
	if c.Username != "" && c.Password != "" {
		cfg.Username = c.Username
		cfg.Password = c.Password
	} else if c.APIKey != "" {
		// API key will be set below
		cfg.APIKey = c.APIKey
	} else {
		// If neither username/password nor API key is provided, we throw an error
		return nil, fmt.Errorf("elasticsearch source %q requires either username/password or an API key", c.Name)
	}

	client, err := elasticsearch.NewBaseClient(cfg)
	if err != nil {
		return nil, err
	}

	// Test connection
	res, err := esapi.InfoRequest{
		Instrument: client.InstrumentationEnabled(),
	}.Do(ctx, client)

	if err != nil {
		return nil, err
	}
	defer res.Body.Close()

	if res.IsError() {

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Add both `username` and `password` to the elasticsearch source in tools.yaml
  2. Or add an `apikey` field with a base64-encoded Elasticsearch API key
  3. Verify YAML field names match exactly: `username`, `password`, `apikey` (lowercase)
  4. Check that env-var templating for credentials resolves to non-empty values

Example fix

// before (tools.yaml)
sources:
  my-es:
    kind: elasticsearch
    addresses:
      - http://localhost:9200
// after
sources:
  my-es:
    kind: elasticsearch
    addresses:
      - http://localhost:9200
    username: elastic
    password: ${ES_PASSWORD}
Defensive patterns

Strategy: validation

Validate before calling

// Go: check before submitting tools.yaml or calling Initialize
if (cfg.Username == "" || cfg.Password == "") && cfg.APIKey == "" {
    return fmt.Errorf("elasticsearch source %q needs username/password or apikey", cfg.Name)
}

Type guard

func hasESCredentials(c elasticsearch.Config) bool {
    return (c.Username != "" && c.Password != "") || c.APIKey != ""
}

Prevention

When it happens

Trigger: Configuring an elasticsearch source in tools.yaml with only `addresses` set; or providing only `username` without `password` (both must be non-empty to take the basic-auth path); or the credential fields are present but resolved to empty strings via templating/env substitution.

Common situations: Pointing at a local dev cluster with xpack.security disabled and omitting credentials; typos in YAML keys (e.g. `apiKey` instead of `apikey`, or `pass` instead of `password`); users assuming anonymous access is allowed.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/627aacbe578ae302. Report an issue: GitHub.