caddyserver/caddy · error

invalid key on line %d: contains whitespace: %s

Error message

invalid key on line %d: contains whitespace: %s

What it means

parseEnvFile rejects a key that contains a space after the `export ` prefix is trimmed. Note the check is only for ' ' (ASCII space) — but any space in a key makes it invalid as an environment variable name anyway. This differs from shells, which would try to execute such a line rather than export it.

Source

Thrown at cmd/main.go:415

			continue
		}

		// split line into key and value
		before, after, isCut := strings.Cut(line, "=")
		if !isCut {
			return nil, fmt.Errorf("can't parse line %d; line should be in KEY=VALUE format", lineNumber)
		}
		key, val := before, after

		// sometimes keys are prefixed by "export " so file can be sourced in bash; ignore it here
		key = strings.TrimPrefix(key, "export ")

		// validate key and value
		if key == "" {
			return nil, fmt.Errorf("missing or empty key on line %d", lineNumber)
		}
		if strings.Contains(key, " ") {
			return nil, fmt.Errorf("invalid key on line %d: contains whitespace: %s", lineNumber, key)
		}
		if strings.HasPrefix(val, " ") || strings.HasPrefix(val, "\t") {
			return nil, fmt.Errorf("invalid value on line %d: whitespace before value: '%s'", lineNumber, val)
		}

		// remove any trailing comment after value
		if commentStart, _, found := strings.Cut(val, "#"); found {
			val = strings.TrimRight(commentStart, " \t")
		}

		// quoted value: support newlines
		if strings.HasPrefix(val, `"`) || strings.HasPrefix(val, "'") {
			quote := string(val[0])
			for !strings.HasSuffix(line, quote) || strings.HasSuffix(line, `\`+quote) {
				val = strings.ReplaceAll(val, `\`+quote, quote)
				if !scanner.Scan() {
					break
				}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Remove ALL spaces around '=' — write `KEY=value`, never `KEY = value`
  2. Replace spaces in names with underscores: `API_KEY=...`
  3. Quote the VALUE if it needs spaces: `KEY='my value'` (quoting is only supported on the value side)

Example fix

# before
API KEY = abc123

# after
API_KEY=abc123
Defensive patterns

Strategy: validation

Validate before calling

grep -nE '^[A-Za-z_][A-Za-z0-9_]*[[:space:]].*=|export [^=]*[[:space:]][^=]*=' env || echo OK

Prevention

When it happens

Trigger: Lines like `MY KEY=value`, `export MY KEY=value`, or a key with a trailing space before '=' such as `KEY =value` (the space becomes part of the key).

Common situations: Writing `KEY = value` with spaces around '=' (common habit from YAML/INI files), descriptive names copied from docs ('API Key=...'), or a stray typo.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/a156b3a834585d9a. Report an issue: GitHub.