FiloSottile/age · error
empty line in armored data
Error message
empty line in armored data
What it means
Inside the armored body, each line must be a non-empty base64 line. An empty line between the header and footer is structurally invalid, so the reader reports this error rather than skipping it, keeping the armor format strict and unambiguous.
Source
Thrown at armor/armor.go:158
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"))
}
if len(line) > format.ColumnsPerLine {
return 0, r.setErr(errors.New("column limit exceeded"))
}
// Reject newline characters ignored by base64.Decode.
if bytes.ContainsAny(line, "\n\r") {
return 0, r.setErr(errors.New("unexpected newline character"))
}
r.unread = r.buf[:]
n, err := base64.StdEncoding.Strict().Decode(r.unread, line)
if err != nil {
return 0, r.setErr(err)
}
r.unread = r.unread[:n]
if n < format.BytesPerLine {
line, err := getLine()
if err != nil {View on GitHub (pinned to b74dce4cdb)
Solutions
- Remove the blank line(s) from the armored body so the payload is contiguous 64-column base64 lines.
- Regenerate the armored file from the original encrypted payload.
- Verify with a text editor that the body has no empty lines between BEGIN and END.
Example fix
// before -----BEGIN AGE ENCRYPTED FILE----- YWJj... ZGVm... -----END AGE ENCRYPTED FILE----- // after -----BEGIN AGE ENCRYPTED FILE----- YWJj... ZGVm... -----END AGE ENCRYPTED FILE-----
Defensive patterns
Strategy: validation
Validate before calling
// Reject blank lines inside the armor body before decrypting
func validateArmorBody(data []byte) error {
inBody := false
for _, l := range bytes.Split(data, []byte('\n')) {
s := strings.TrimSpace(string(l))
if strings.HasPrefix(s, "-----BEGIN") {
inBody = true
continue
}
if strings.HasPrefix(s, "-----END") {
return nil
}
if inBody && s == "" {
return errors.New("empty line in armored data")
}
}
return errors.New("no footer")
} Try / catch
_, err := io.ReadAll(armor.NewReader(f))
if err != nil && err.Error() == "empty line in armored data" {
// remove blank lines from the armor body and retry
} Prevention
- Keep the armor body contiguous with no blank lines.
- Disable editors/tools that reformat or insert blank lines in payload files.
- Regenerate the armored file rather than repairing it by hand when unsure.
When it happens
Trigger: Reading an armored file whose payload contains a blank line — typically from editors inserting blank lines, mail clients reformatting, or manual edits to the armored data.
Common situations: Pasting armor through email clients that mangle line structure, formatting tools that insert blank lines at column boundaries, or diff/merge artifacts leaving an empty line in the base64 body.
Related errors
- trailing data after armored file
- too much trailing whitespace
- too much leading whitespace
- column limit exceeded
- unexpected newline character
AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31).
Data as JSON: /api/errors/b7b4c2199e7d4b88.
Report an issue: GitHub.