JuliusBrussee/caveman · error

envelope: unwrap data key: %w

Error message

envelope: unwrap data key: %w

What it means

Fires in open() when secretbox.DecryptPayloadKey cannot unwrap the base64-decoded WrappedDataKey from the envelope Metadata — i.e. the wrapped key blob is corrupt, truncated, tampered with, or was produced by a different key-encryption key. This happens before any payload decryption, so the failure is about the key layer, not the ciphertext itself.

Source

Thrown at shared/platform/envelope/envelope.go:146

	}
	aad, scopeHash, err := scopeAAD(scope)
	if err != nil {
		return nil, err
	}
	if meta.ScopeHash != scopeHash {
		return nil, fmt.Errorf("envelope: tenant scope mismatch")
	}
	return open(ciphertext, meta, aad)
}

func open(ciphertext []byte, meta Metadata, aad []byte) ([]byte, error) {
	wrapped, err := base64.StdEncoding.DecodeString(meta.WrappedDataKey)
	if err != nil {
		return nil, fmt.Errorf("envelope: decode wrapped key: %w", err)
	}
	dataKey, err := secretbox.DecryptPayloadKey(wrapped)
	if err != nil {
		return nil, fmt.Errorf("envelope: unwrap data key: %w", err)
	}
	block, err := aes.NewCipher(dataKey)
	if err != nil {
		return nil, fmt.Errorf("envelope: aes: %w", err)
	}
	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return nil, fmt.Errorf("envelope: gcm: %w", err)
	}
	ns := gcm.NonceSize()
	if len(ciphertext) < ns {
		return nil, fmt.Errorf("envelope: ciphertext too short")
	}
	nonce, ct := ciphertext[:ns], ciphertext[ns:]
	plaintext, err := gcm.Open(nil, nonce, ct, aad)
	if err != nil {
		return nil, fmt.Errorf("envelope: open: %w", err)
	}

View on GitHub (pinned to 766dce6b13)

Solutions

  1. Verify the record's Metadata (WrappedDataKey) was not truncated or altered in storage; re-seal the payload if the metadata is corrupt
  2. Confirm the KMS/master key used to wrap data keys has not been rotated or deleted since sealing
  3. Ensure base64 decoding succeeded for the right field and no whitespace or padding was stripped in transit
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at shared/platform/envelope/envelope.go:146 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18). Data as JSON: /api/errors/fc7a4f6f54a0c53f. Report an issue: GitHub.