{"record":{"id":"bcd675df81c4d541","repo":"caddyserver/caddy","slug":"invalid-value-on-line-d-whitespace-before-value","errorCode":null,"errorMessage":"invalid value on line %d: whitespace before value: '%s'","messagePattern":"invalid value on line (.+?): whitespace before value: '(.+?)'","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/main.go","lineNumber":418,"sourceCode":"\t\t// split line into key and value\n\t\tbefore, after, isCut := strings.Cut(line, \"=\")\n\t\tif !isCut {\n\t\t\treturn nil, fmt.Errorf(\"can't parse line %d; line should be in KEY=VALUE format\", lineNumber)\n\t\t}\n\t\tkey, val := before, after\n\n\t\t// sometimes keys are prefixed by \"export \" so file can be sourced in bash; ignore it here\n\t\tkey = strings.TrimPrefix(key, \"export \")\n\n\t\t// validate key and value\n\t\tif key == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"missing or empty key on line %d\", lineNumber)\n\t\t}\n\t\tif strings.Contains(key, \" \") {\n\t\t\treturn nil, fmt.Errorf(\"invalid key on line %d: contains whitespace: %s\", lineNumber, key)\n\t\t}\n\t\tif strings.HasPrefix(val, \" \") || strings.HasPrefix(val, \"\\t\") {\n\t\t\treturn nil, fmt.Errorf(\"invalid value on line %d: whitespace before value: '%s'\", lineNumber, val)\n\t\t}\n\n\t\t// remove any trailing comment after value\n\t\tif commentStart, _, found := strings.Cut(val, \"#\"); found {\n\t\t\tval = strings.TrimRight(commentStart, \" \\t\")\n\t\t}\n\n\t\t// quoted value: support newlines\n\t\tif strings.HasPrefix(val, `\"`) || strings.HasPrefix(val, \"'\") {\n\t\t\tquote := string(val[0])\n\t\t\tfor !strings.HasSuffix(line, quote) || strings.HasSuffix(line, `\\`+quote) {\n\t\t\t\tval = strings.ReplaceAll(val, `\\`+quote, quote)\n\t\t\t\tif !scanner.Scan() {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tlineNumber++\n\t\t\t\tline = strings.ReplaceAll(scanner.Text(), `\\`+quote, quote)\n\t\t\t\tval += \"\\n\" + line","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/main.go#L400-L436","documentation":"parseEnvFile rejects a value that begins with a space or tab. Because the line is trimmed but the split preserves everything after '=', `KEY= value` yields a value starting with ' ', which Caddy treats as a user error rather than silently trimming (unlike dotenv implementations). Whitespace elsewhere in the value is fine.","triggerScenarios":"Writing `KEY= value` or `KEY=\tvalue` — any whitespace directly after the '=' sign. Very commonly paired with `KEY = value` style, where the leading space of the value is the reported problem.","commonSituations":"Copy-paste from YAML/JSON where alignment introduces spaces; editors auto-formatting; users expecting dotenv semantics where `KEY= value` trims to `value`.","solutions":["Delete whitespace immediately after '=': `KEY=value`","If the value genuinely starts with spaces, quote it: `KEY=\"  padded\"` — quoted values are supported and preserve inner whitespace","Run a quick check: `grep -nE '^[A-Za-z_][A-Za-z0-9_]*=[ \\t]' env` to find every offender"],"exampleFix":"# before\nCF_API_TOKEN= v2.0-xyz\n\n# after\nCF_API_TOKEN=v2.0-xyz","handlingStrategy":"validation","validationCode":"grep -nE '^[A-Za-z_][A-Za-z0-9_]*=[[:space:]]' env && echo 'whitespace after = found' || echo OK","typeGuard":null,"tryCatchPattern":null,"preventionTips":["No space directly after '='","Quote values that intentionally start with whitespace"],"tags":["caddy","env-file","parsing","configuration"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}