docker/cli · error · invalidParameterErr
failed to parse custom headers from
Error message
failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs
What it means
Returned by withCustomHeadersFromEnv() when the DOCKER_CUSTOM_HEADERS environment variable is set but its value cannot be parsed as a CSV record of header pairs. The function constructs a csv.Reader over the value (cli_options.go:176-177) and treats any csv.Read error as a hard invalidParameter failure. CSV parsing fails on issues like unbalanced quotes or a stray quote inside an unquoted field.
Solutions
- Format DOCKER_CUSTOM_HEADERS as comma-separated key=value pairs: 'X-Custom=value,Another=otherval'.
- If a value contains a comma, wrap the entire pair in double quotes: '"Cache-Control=max-age=0, no-cache"'.
- Ensure all double-quotes are balanced; escape literal quotes by doubling them inside a quoted field per RFC 4180.
- Validate the value with a quick CSV parse before exporting it in scripts.
Example fix
// before export DOCKER_CUSTOM_HEADERS='X-Custom="header-value' # unbalanced quote -> CSV error // after export DOCKER_CUSTOM_HEADERS='X-Custom=header-value,Other=ok'
Defensive patterns
Strategy: validation
Validate before calling
// Validate DOCKER_CUSTOM_HEADERS parses as CSV before exporting.
func validateCustomHeadersCSV(value string) error {
r := csv.NewReader(strings.NewReader(value))
if _, err := r.Read(); err != nil {
return fmt.Errorf("DOCKER_CUSTOM_HEADERS is not valid CSV of key=value pairs: %w", err)
}
return nil
} Try / catch
if _, err := command.WithCustomHeadersFromEnv(); err != nil {
// hint: balance quotes, wrap comma-containing values in quotes, RFC 4180 escaping
} Prevention
- Quote any header value containing a comma by wrapping the whole key=value pair.
- Double quotes inside quoted fields per RFC 4180.
- Lint the value with a CSV parser in CI.
When it happens
Trigger: Setting DOCKER_CUSTOM_HEADERS to a value with CSV-structural problems: an unbalanced double-quote (e.g. 'X-Foo="bar'), an embedded quote in an unquoted field, or a record that the CSV reader rejects. The parser expects comma-separated key=value tokens, optionally quoted as a whole CSV field.
Common situations: Users quoting only one side of a header value, pasting a header value that itself contains a comma without wrapping the whole key=value in quotes, or copy-pasting JSON-like values that contain stray quotes.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to set custom headers from
- failed to set custom headers from
- DOCKER_BUILDKIT environment variable expects boolean value
- failed to read credentials from DOCKER_AUTH_CONFIG
- failed to parse hook template
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/5507b510ad014fb0.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/cli_options.go:179
// environment variable is the equivalent to the HttpHeaders field in the
// configuration file.
//
// WARNING: If both config and environment-variable are set, the environment-
// variable currently overrides all headers set in the configuration file.
// This behavior may change in a future update, as we are considering the
// environment-variable to be appending to existing headers (and to only
// override headers with the same name).
//
// TODO(thaJeztah): this is a client Option, and should be moved to the client. It is non-exported for that reason.
func withCustomHeadersFromEnv() (client.Opt, error) {
value := os.Getenv(envOverrideHTTPHeaders)
if value == "" {
return nil, nil
}
csvReader := csv.NewReader(strings.NewReader(value))
fields, err := csvReader.Read()
if err != nil {
return nil, invalidParameter(fmt.Errorf(
"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs",
envOverrideHTTPHeaders,
))
}
if len(fields) == 0 {
return nil, nil
}
env := map[string]string{}
for _, kv := range fields {
k, v, hasValue := strings.Cut(kv, "=")
// Only strip whitespace in keys; preserve whitespace in values.
k = strings.TrimSpace(k)
if k == "" {
return nil, invalidParameter(fmt.Errorf(
`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,View on GitHub (pinned to 4f84911bfe)