{"record":{"id":"5507b510ad014fb0","repo":"docker/cli","slug":"failed-to-parse-custom-headers-from-s-environment","errorCode":null,"errorMessage":"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs","messagePattern":"failed to parse custom headers from (.+?) environment variable: value must be formatted as comma-separated key=value pairs","errorType":"validation","errorClass":"invalidParameterErr","httpStatus":null,"severity":"error","filePath":"cli/command/cli_options.go","lineNumber":179,"sourceCode":"// environment variable is the equivalent to the HttpHeaders field in the\n// configuration file.\n//\n// WARNING: If both config and environment-variable are set, the environment-\n// variable currently overrides all headers set in the configuration file.\n// This behavior may change in a future update, as we are considering the\n// environment-variable to be appending to existing headers (and to only\n// override headers with the same name).\n//\n// TODO(thaJeztah): this is a client Option, and should be moved to the client. It is non-exported for that reason.\nfunc withCustomHeadersFromEnv() (client.Opt, error) {\n\tvalue := os.Getenv(envOverrideHTTPHeaders)\n\tif value == \"\" {\n\t\treturn nil, nil\n\t}\n\tcsvReader := csv.NewReader(strings.NewReader(value))\n\tfields, err := csvReader.Read()\n\tif err != nil {\n\t\treturn nil, invalidParameter(fmt.Errorf(\n\t\t\t\"failed to parse custom headers from %s environment variable: value must be formatted as comma-separated key=value pairs\",\n\t\t\tenvOverrideHTTPHeaders,\n\t\t))\n\t}\n\tif len(fields) == 0 {\n\t\treturn nil, nil\n\t}\n\n\tenv := map[string]string{}\n\tfor _, kv := range fields {\n\t\tk, v, hasValue := strings.Cut(kv, \"=\")\n\n\t\t// Only strip whitespace in keys; preserve whitespace in values.\n\t\tk = strings.TrimSpace(k)\n\n\t\tif k == \"\" {\n\t\t\treturn nil, invalidParameter(fmt.Errorf(\n\t\t\t\t`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/cli_options.go#L161-L197","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nexport DOCKER_CUSTOM_HEADERS='X-Custom=\"header-value'   # unbalanced quote -> CSV error\n// after\nexport DOCKER_CUSTOM_HEADERS='X-Custom=header-value,Other=ok'","handlingStrategy":"validation","validationCode":"// Validate DOCKER_CUSTOM_HEADERS parses as CSV before exporting.\nfunc validateCustomHeadersCSV(value string) error {\n    r := csv.NewReader(strings.NewReader(value))\n    if _, err := r.Read(); err != nil {\n        return fmt.Errorf(\"DOCKER_CUSTOM_HEADERS is not valid CSV of key=value pairs: %w\", err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, err := command.WithCustomHeadersFromEnv(); err != nil {\n    // hint: balance quotes, wrap comma-containing values in quotes, RFC 4180 escaping\n}","preventionTips":["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."],"tags":["environment-variable","http-headers","configuration","csv-parsing"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}