googleapis/mcp-toolbox · error

error parsing environment variables: %s

Error message

error parsing environment variables: %s

What it means

ParseConfig wraps any error from parseEnv (missing or failed environment variable substitution) with this message. It means the raw config YAML could not have its ${VAR} placeholders resolved, so parsing aborts before YAML decoding. The inner error names the missing variable(s) or the substitution failure.

Source

Thrown at cmd/internal/config.go:193

		if i >= index {
			break
		}
		if r == '\n' {
			line++
			column = 1
		} else {
			column++
		}
	}
	return line, column
}

func (p *ConfigParser) ParseConfig(ctx context.Context, raw []byte) (Config, error) {
	var config Config
	// Replace environment variables if found
	output, err := p.parseEnv(string(raw))
	if err != nil {
		return config, fmt.Errorf("error parsing environment variables: %s", err)
	}
	raw = []byte(output)

	raw, err = ConvertConfig(ctx, raw)
	if err != nil {
		return config, fmt.Errorf("error converting config file: %s", err)
	}

	// Parse contents
	config.Sources, config.AuthServices, config.EmbeddingModels, config.Tools, config.Prompts, config.Groups, err = server.UnmarshalPrimitiveConfig(ctx, raw)
	if err != nil {
		return config, err
	}
	return config, nil
}

// ConvertConfig converts configuration file to flat format and rewrites toolsets
// to the group kind.

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Read the wrapped inner message, export/provide the listed environment variables, and retry.
  2. Fix malformed ${...} placeholder syntax in the config file.
  3. Verify the intended environment (shell profile, CI secrets, k8s env) is actually the one in effect.
  4. Run `toolbox --env-file .env` or equivalent to load variables from a file.

Example fix

// before: config: url: ${API_URL}, API_URL unset
Config, err := parser.ParseConfig(ctx, raw) // "error parsing environment variables: environment variable not found: API_URL"
// after
os.Setenv("API_URL", "https://api.example.com")
Config, err := parser.ParseConfig(ctx, raw) // succeeds
Defensive patterns

Strategy: try-catch

Validate before calling

re := regexp.MustCompile(`\$\{[A-Za-z_][A-Za-z0-9_]*\}`)
for _, m := range re.FindAllStringSubmatch(string(raw), -1) {
    if os.Getenv(m[1]) == "" { return fmt.Errorf("missing env var %s", m[1]) }
}

Try / catch

cfg, err := parser.ParseConfig(ctx, raw)
if err != nil {
    var envErr = "error parsing environment variables"
    if strings.Contains(err.Error(), envErr) {
        log.Fatalf("fix env vars for config load: %v", err) // inner message names the var(s)
    }
}

Prevention

When it happens

Trigger: Loading a toolbox config whose ${VAR} placeholders reference unset environment variables, or whose substitution itself fails (e.g. malformed placeholder syntax), via LoadConfig or LoadAndMergeConfigs.

Common situations: Secrets not present in the deployment environment; wrong shell profile loaded; config templated for one environment and run in another; invalid placeholder syntax like ${VAR (unclosed).

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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