ory/hydra · error
cookiex: cannot marshal envelope
Error message
cookiex: cannot marshal envelope
What it means
Returned by Codec.seal when json.Marshal of the internal envelope{IssuedAt, Values} fails. Because Values is json.RawMessage produced by the preceding successful marshal, this error is practically unreachable and would indicate memory corruption or an invalid RawMessage injected into the envelope.
Source
Thrown at oryx/cookiex/cookiex.go:138
IssuedAt int64 `json:"iat"`
Values json.RawMessage `json:"v"`
}
// aad binds a ciphertext to this codec's purpose and the cookie name, so a
// sealed value cannot be replayed as a different cookie or in a different
// context, even under the same key.
func (c *Codec[T]) aad(name string) []byte {
return []byte(aadPrefix + "|" + c.purpose + "|" + name)
}
func (c *Codec[T]) seal(name string, value T) (string, error) {
payload, err := json.Marshal(value)
if err != nil {
return "", errors.Wrap(err, "cookiex: cannot marshal cookie value")
}
plaintext, err := json.Marshal(envelope{IssuedAt: c.now().Unix(), Values: payload})
if err != nil {
return "", errors.Wrap(err, "cookiex: cannot marshal envelope")
}
a, err := aead.New(c.keys[0])
if err != nil {
return "", errors.Wrap(err, "cookiex: cannot create AEAD")
}
// The nonce is prepended to the ciphertext. AEADs that manage the nonce
// internally report a nonce size of zero, so this also covers them.
nonce := make([]byte, a.NonceSize())
if _, err := rand.Read(nonce); err != nil {
return "", errors.Wrap(err, "cookiex: cannot generate nonce")
}
sealed := a.Seal(nonce, nonce, plaintext, c.aad(name))
return formatPrefix + base64.RawURLEncoding.EncodeToString(sealed), nil
}
func (c *Codec[T]) open(name, value string) (T, error) {
var zero T
raw, err := base64.RawURLEncoding.DecodeString(strings.TrimPrefix(value, formatPrefix))View on GitHub (pinned to 4174065ffb)
Solutions
- Inspect the wrapped error; if reachable, the RawMessage payload was mutated between marshals
- Ensure the payload type T does not produce invalid raw JSON fragments
- Treat as an internal invariant violation and fail the Set call
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at oryx/cookiex/cookiex.go:138 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/f781ef3f64ce91e9.
Report an issue: GitHub.