{"record":{"id":"7084c5195867d836","repo":"FiloSottile/age","slug":"failed-to-set-up-hpke-sender-v","errorCode":null,"errorMessage":"failed to set up HPKE sender: %v","messagePattern":"failed to set up HPKE sender: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tag/tag.go","lineNumber":144,"sourceCode":"\treturn tag[:4], nil\n}\n\n// WrapWithLabels implements [age.RecipientWithLabels], returning a single\n// \"postquantum\" label if r is a hybrid P-256 + ML-KEM-768 recipient. This\n// ensures a hybrid Recipient can't be mixed with other recipients that would\n// defeat its post-quantum security.\n//\n// To unsafely bypass this restriction, wrap Recipient in an [age.Recipient]\n// type that doesn't expose WrapWithLabels.\nfunc (r *Recipient) WrapWithLabels(fileKey []byte) ([]*age.Stanza, []string, error) {\n\tlabel, arg := \"age-encryption.org/p256tag\", \"p256tag\"\n\tif r.Hybrid() {\n\t\tlabel, arg = \"age-encryption.org/mlkem768p256tag\", \"mlkem768p256tag\"\n\t}\n\n\tenc, s, err := hpke.NewSender(r.pk, hpke.HKDFSHA256(), hpke.ChaCha20Poly1305(), []byte(label))\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to set up HPKE sender: %v\", err)\n\t}\n\tct, err := s.Seal(nil, fileKey)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to encrypt file key: %v\", err)\n\t}\n\n\ttag, err := r.Tag(enc)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to compute tag: %v\", err)\n\t}\n\n\tl := &age.Stanza{\n\t\tType: arg,\n\t\tArgs: []string{\n\t\t\tformat.EncodeToString(tag[:4]),\n\t\t\tformat.EncodeToString(enc),\n\t\t},\n\t\tBody: ct,","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/tag/tag.go#L126-L162","documentation":"WrapWithLabels creates an HPKE sender against the recipient's public key using HKDF-SHA256, ChaCha20Poly1305, and a KEM-specific info label. NewSender validates the KEM/AEAD/id combination; failure here means the internal recipient key or the HPKE parameter set was rejected.","triggerScenarios":"Calling Wrap/WrapWithLabels on a Recipient whose internal hpke.PublicKey is invalid or whose KEM conflicts with the chosen suites — practically only reachable if the Recipient was constructed with a zero value (&tag.Recipient{} with nil pk) or corrupted via unsafe code, since exported constructors validate keys.","commonSituations":"Constructing Recipient via reflection/unsafe or a zero-value struct instead of NewClassicRecipient/NewHybridRecipient; deserializing a Recipient from an external format; a mismatched hpke library version where KEM IDs changed.","solutions":["Always obtain the Recipient from tag.ParseRecipient, NewClassicRecipient, or NewHybridRecipient — never instantiate tag.Recipient directly.","Check the wrapped %v detail for the underlying HPKE error and confirm your filippo.io/hpke version is current (go get -u filippo.io/hpke).","Verify the key was not truncated or mutated between construction and use.","If serializing recipients, serialize the raw bytes and re-parse with ParseRecipient rather than persisting structs."],"exampleFix":"// before\nr := &tag.Recipient{} // zero value, nil pk\nstanzas, err := r.Wrap(fileKey)\n// after\nr, err := tag.NewHybridRecipient(rawPubKey)\nif err != nil { return err }\nstanzas, err := r.Wrap(fileKey)","handlingStrategy":"validation","validationCode":"r, err := tag.NewHybridRecipient(pubKey) // or NewClassicRecipient / ParseRecipient\nif err != nil {\n    return err // fail fast before any Wrap call\n}","typeGuard":"func constructedViaAPI(r *tag.Recipient) bool { return r != nil } // zero-value Recipient{} has nil pk and will fail Wrap","tryCatchPattern":"stanzas, _, err := r.WrapWithLabels(fileKey)\nif err != nil {\n    return fmt.Errorf(\"wrap failed: %w\", err)\n}","preventionTips":["Never construct tag.Recipient directly; always use NewClassicRecipient, NewHybridRecipient, or ParseRecipient.","Keep filippo.io/hpke up to date.","Log the wrapped %v detail for diagnosis."],"tags":["go","age","hpke","sender-setup","post-quantum"],"backgroundTag":"hpke-sender-init-failed","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}