FiloSottile/age · error
too much leading whitespace
Error message
too much leading whitespace
What it means
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.
Source
Thrown at armor/armor.go:141
return errors.New("trailing data after armored file")
}
if len(buf) == maxWhitespace {
return errors.New("too much trailing whitespace")
}
return io.EOF
}
var removedWhitespace int
for !r.started {
line, err := getLine()
if err != nil {
return 0, r.setErr(err)
}
// Ignore leading whitespace.
if len(bytes.TrimSpace(line)) == 0 {
removedWhitespace += len(line) + 1
if removedWhitespace > maxWhitespace {
return 0, r.setErr(errors.New("too much leading whitespace"))
}
continue
}
if string(line) != Header {
return 0, r.setErr(fmt.Errorf("invalid first line: %q", line))
}
r.started = true
}
line, err := getLine()
if err != nil {
return 0, r.setErr(err)
}
if string(line) == Footer {
return 0, r.setErr(drainTrailing())
}
if len(line) == 0 {
return 0, r.setErr(errors.New("empty line in armored data"))
}View on GitHub (pinned to b74dce4cdb)
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.
Example fix
// before
cat preamble.txt armor.age > combined.age
// after
awk '/-----BEGIN AGE ENCRYPTED FILE-----/{f=1} f' combined.age > armor.age Defensive patterns
Strategy: validation
Validate before calling
// Ensure the stream starts with the armor header before decrypting
func skipLeadingBlankLines(r io.Reader) (io.Reader, error) {
br := bufio.NewReader(r)
for {
line, err := br.ReadString('\n')
if err != nil {
return nil, err
}
if strings.TrimSpace(line) != "" {
return io.MultiReader(strings.NewReader(line), br), nil
}
}
} Type guard
func isArmorHeader(line string) bool {
return strings.TrimSpace(line) == "-----BEGIN AGE ENCRYPTED FILE-----"
} Try / catch
out, err := io.ReadAll(armor.NewReader(f))
if err != nil && err.Error() == "too much leading whitespace" {
// strip leading blank lines and retry
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- too much trailing whitespace
- trailing data after armored file
- empty line in armored data
- column limit exceeded
- unexpected newline character
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/e6867be73d8aadf4.
Report an issue: GitHub.