{"record":{"id":"e6867be73d8aadf4","repo":"FiloSottile/age","slug":"too-much-leading-whitespace","errorCode":null,"errorMessage":"too much leading whitespace","messagePattern":"too much leading whitespace","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"armor/armor.go","lineNumber":141,"sourceCode":"\t\t\treturn errors.New(\"trailing data after armored file\")\n\t\t}\n\t\tif len(buf) == maxWhitespace {\n\t\t\treturn errors.New(\"too much trailing whitespace\")\n\t\t}\n\t\treturn io.EOF\n\t}\n\n\tvar removedWhitespace int\n\tfor !r.started {\n\t\tline, err := getLine()\n\t\tif err != nil {\n\t\t\treturn 0, r.setErr(err)\n\t\t}\n\t\t// Ignore leading whitespace.\n\t\tif len(bytes.TrimSpace(line)) == 0 {\n\t\t\tremovedWhitespace += len(line) + 1\n\t\t\tif removedWhitespace > maxWhitespace {\n\t\t\t\treturn 0, r.setErr(errors.New(\"too much leading whitespace\"))\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif string(line) != Header {\n\t\t\treturn 0, r.setErr(fmt.Errorf(\"invalid first line: %q\", line))\n\t\t}\n\t\tr.started = true\n\t}\n\tline, err := getLine()\n\tif err != nil {\n\t\treturn 0, r.setErr(err)\n\t}\n\tif string(line) == Footer {\n\t\treturn 0, r.setErr(drainTrailing())\n\t}\n\tif len(line) == 0 {\n\t\treturn 0, r.setErr(errors.New(\"empty line in armored data\"))\n\t}","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/armor/armor.go#L123-L159","documentation":"Before parsing the armor header, the reader skips leading whitespace, but only up to maxWhitespace bytes total. If the file starts with more whitespace than allowed, reading fails with this error, because such input is not a plausibly valid armored file.","triggerScenarios":"Calling Read (or age.Decrypt) on an armored stream that begins with more than maxWhitespace bytes of blank lines, spaces, tabs, or CR/LF before the '-----BEGIN AGE ENCRYPTED FILE-----' header.","commonSituations":"Email or chat pastes with many leading blank lines, concatenated text files where the armor begins after a large preamble, or templates/heredocs emitting excessive blank lines before the payload.","solutions":["Strip the leading whitespace so the file begins with the BEGIN header (e.g. sed/awk from the first '-----BEGIN' line).","Fix the tool or script emitting the whitespace preamble.","Regenerate the armored file directly with the age CLI without a preamble."],"exampleFix":"// before\ncat preamble.txt armor.age > combined.age\n// after\nawk '/-----BEGIN AGE ENCRYPTED FILE-----/{f=1} f' combined.age > armor.age","handlingStrategy":"validation","validationCode":"// Ensure the stream starts with the armor header before decrypting\nfunc skipLeadingBlankLines(r io.Reader) (io.Reader, error) {\n    br := bufio.NewReader(r)\n    for {\n        line, err := br.ReadString('\\n')\n        if err != nil {\n            return nil, err\n        }\n        if strings.TrimSpace(line) != \"\" {\n            return io.MultiReader(strings.NewReader(line), br), nil\n        }\n    }\n}","typeGuard":"func isArmorHeader(line string) bool {\n    return strings.TrimSpace(line) == \"-----BEGIN AGE ENCRYPTED FILE-----\"\n}","tryCatchPattern":"out, err := io.ReadAll(armor.NewReader(f))\nif err != nil && err.Error() == \"too much leading whitespace\" {\n    // strip leading blank lines and retry\n}","preventionTips":["Start armored files directly with the BEGIN header.","Trim preamble text emitted by templates/heredocs.","Validate the first non-blank line equals the armor Header before decrypting."],"tags":["go","age","armor","reader","whitespace"],"backgroundTag":"excessive-whitespace","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}