{"record":{"id":"fd39c917730b0b06","repo":"FiloSottile/age","slug":"column-limit-exceeded","errorCode":null,"errorMessage":"column limit exceeded","messagePattern":"column limit exceeded","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"armor/armor.go","lineNumber":161,"sourceCode":"\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}\n\tif len(line) > format.ColumnsPerLine {\n\t\treturn 0, r.setErr(errors.New(\"column limit exceeded\"))\n\t}\n\t// Reject newline characters ignored by base64.Decode.\n\tif bytes.ContainsAny(line, \"\\n\\r\") {\n\t\treturn 0, r.setErr(errors.New(\"unexpected newline character\"))\n\t}\n\tr.unread = r.buf[:]\n\tn, err := base64.StdEncoding.Strict().Decode(r.unread, line)\n\tif err != nil {\n\t\treturn 0, r.setErr(err)\n\t}\n\tr.unread = r.unread[:n]\n\n\tif n < format.BytesPerLine {\n\t\tline, err := getLine()\n\t\tif err != nil {\n\t\t\treturn 0, r.setErr(err)\n\t\t}\n\t\tif string(line) != Footer {","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/armor/armor.go#L143-L179","documentation":"Armor lines are restricted to format.ColumnsPerLine (64) characters, matching the encoder's output. A longer line means the data was not produced by this armor format (or was reformatted), so the reader rejects it instead of guessing how to split it.","triggerScenarios":"Reading an armored file where a body line exceeds 64 characters — e.g. armor reflowed by a text editor with a different wrap width, MIME base64 from email (76-char lines) pasted into an age armor envelope, or hand-concatenated base64 lines.","commonSituations":"Extracting base64 from a MIME email attachment into an age armor template, editors with word-wrap rewriting the file, or scripts joining base64 lines into one long line.","solutions":["Re-wrap body lines to at most 64 columns (e.g. fold -w 64) and retry decryption.","Re-obtain the armored file from its original source or re-run the age CLI to produce correctly wrapped armor.","Disable editor word-wrap and avoid MIME re-encoding when transferring .age files."],"exampleFix":"// before: one 200-char base64 line in the armor body\n// after\nfold -w 64 longline.age > wrapped.age","handlingStrategy":"validation","validationCode":"// Check armor line widths before decrypting\nfunc checkLineLengths(data []byte) error {\n    for _, l := range bytes.Split(data, []byte('\\n')) {\n        l = bytes.TrimRight(l, \"\\r\")\n        if !bytes.HasPrefix(l, []byte(\"-----\")) && len(l) > 64 {\n            return fmt.Errorf(\"line too long: %d\", len(l))\n        }\n    }\n    return nil\n}","typeGuard":"func isWrappedArmorLine(line []byte) bool {\n    return len(line) <= 64\n}","tryCatchPattern":"_, err := io.ReadAll(armor.NewReader(f))\nif err != nil && err.Error() == \"column limit exceeded\" {\n    // re-wrap lines with fold -w 64 or re-export the armor\n}","preventionTips":["Keep armor lines at the encoder's 64-column width.","Do not paste base64 from MIME emails (76-char lines) into age armor.","Disable word-wrap when editing armored files."],"tags":["go","age","armor","reader","line-length"],"backgroundTag":"malformed-armored-file","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}