{"record":{"id":"e71b6156f521eea1","repo":"FiloSottile/age","slug":"no-recipient-stanzas","errorCode":null,"errorMessage":"no recipient stanzas","messagePattern":"no recipient stanzas","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/format/format.go","lineNumber":147,"sourceCode":"\t\t}\n\t}\n\tif _, err := io.WriteString(w, \"\\n\"); err != nil {\n\t\treturn err\n\t}\n\tww := NewWrappedBase64Encoder(b64, w)\n\tif _, err := ww.Write(r.Body); err != nil {\n\t\treturn err\n\t}\n\tif err := ww.Close(); err != nil {\n\t\treturn err\n\t}\n\t_, err := io.WriteString(w, \"\\n\")\n\treturn err\n}\n\nfunc (h *Header) MarshalWithoutMAC(w io.Writer) error {\n\tif len(h.Recipients) == 0 {\n\t\treturn errors.New(\"no recipient stanzas\")\n\t}\n\tif _, err := io.WriteString(w, intro); err != nil {\n\t\treturn err\n\t}\n\tfor _, r := range h.Recipients {\n\t\tif err := r.Marshal(w); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t_, err := fmt.Fprintf(w, \"%s\", footerPrefix)\n\treturn err\n}\n\nfunc (h *Header) Marshal(w io.Writer) error {\n\tif err := h.MarshalWithoutMAC(w); err != nil {\n\t\treturn err\n\t}\n\tmac := b64.EncodeToString(h.MAC)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/internal/format/format.go#L129-L165","documentation":"MarshalWithoutMAC refuses to serialize a Header that has no recipient stanzas. An age file header must contain at least one recipient stanza wrapping the file key; writing a header with zero recipients would produce a structurally invalid file no implementation can decrypt. It is thrown as a guard before the intro line is written.","triggerScenarios":"Calling age.Marshal (or headerMAC, which calls MarshalWithoutMAC) with a Recipients list of length zero — e.g. age Encrypt with no Recipient arguments.","commonSituations":"Building recipients programmatically from user input or config where an empty list slips through; piping recipients parsed from a file that turned out empty; forgetting to add any recipient before Encrypt.","solutions":["Ensure at least one age.Recipient is added before calling age.Marshal / Encrypt.","Validate len(recipients) > 0 in caller code and surface a clear error to the user instead of encrypting.","If recipients come from parsed input, check the parse produced at least one entry and reject empty input up front."],"exampleFix":"// before\nif err := age.Encrypt(out, recipients...); ... // recipients empty\n// after\nif len(recipients) == 0 {\n    return errors.New(\"no recipients specified\")\n}\nw, err := age.Encrypt(out, recipients...)","handlingStrategy":"validation","validationCode":"if len(recipients) == 0 {\n    return errors.New(\"at least one recipient is required\")\n}\nw, err := age.Encrypt(out, recipients...)","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if err.Error() == \"no recipient stanzas\" {\n        return errors.New(\"encrypt: no recipients configured\")\n    }\n    return err\n}","preventionTips":["Always build the recipient list explicitly and assert non-empty before Encrypt.","Fail fast at config-load time if no recipients are configured.","Unit-test the empty-recipient code path."],"tags":["encryption","header","validation"],"backgroundTag":"no-recipient-stanzas","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}