getsops/sops · critical
Failed to decrypt original mac: %w
Error message
Failed to decrypt original mac: %w
What it means
sops stores a MessageAuthenticationCode in the tree metadata, itself encrypted with the data key. During decryption DataWithFormat calls cipher.Decrypt on that MAC using the recovered key and the LastModified timestamp; if the ciphertext MAC cannot be decrypted, sops fails with this error. This usually means the metadata is unreadable with the key that was used, or the metadata was corrupted or re-serialized with a changed timestamp.
Source
Thrown at decrypt/decrypt.go:64
}
// Decrypt the tree
cipher := aes.NewCipher()
mac, err := tree.Decrypt(key, cipher)
if err != nil {
return nil, err
}
// Compute the hash of the cleartext tree and compare it with
// the one that was stored in the document. If they match,
// integrity was preserved
originalMac, err := cipher.Decrypt(
tree.Metadata.MessageAuthenticationCode,
key,
tree.Metadata.LastModified.Format(time.RFC3339),
)
if err != nil {
return nil, fmt.Errorf("Failed to decrypt original mac: %w", err)
}
if originalMac != mac {
return nil, fmt.Errorf("Failed to verify data integrity. expected mac %q, got %q", originalMac, mac)
}
return store.EmitPlainFile(tree.Branches)
}
// Data is a helper that takes encrypted data and a format string,
// decrypts the data and returns its cleartext in an []byte.
// The format string can be `json`, `yaml`, `ini`, `dotenv` or `binary`.
// If the format string is empty, binary format is assumed.
func Data(data []byte, format string) (cleartext []byte, err error) {
formatFmt := FormatFromString(format)
return DataWithFormat(data, formatFmt)
}
View on GitHub (pinned to 13442bb981)
Solutions
- Confirm you can decrypt with the CLI (sops -d file) to isolate whether credentials or the file are at fault
- Check KMS/age credentials: AWS_PROFILE, AWS region, age identity file (SOPS_AGE_KEY_FILE), key groups present
- Do not edit the sops: metadata block or reformat the file; if it was altered, restore the original from git or re-encrypt the plaintext
- If the KMS key was rotated/disabled, temporarily re-enable it or decrypt with the backup key group
Example fix
// before (no key services configured, wrong key used)
plain, err := decrypt.Data(encBytes, "yaml")
// after
svcs := []keyservice.KeyServiceClient{keyservice.NewKeyService(keyservice.NewAWSKMSKeyService())}
plain, err := decrypt.DataWithKeyServices(encBytes, "yaml", svcs) Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: confirm at least one key service is reachable before decrypting
svc := keyservice.NewKeyService(keyservice.NewAWSKMSKeyService())
if _, err := svc.KeyMetadatasAvailable(ctx, tree.Metadata); err != nil {
return fmt.Errorf("no decryption keys available: %w", err)
} Try / catch
plain, err := decrypt.DataWithFormat(encBytes, formatFmt)
if err != nil {
if strings.Contains(err.Error(), "Failed to decrypt original mac") {
return fmt.Errorf("decryption key mismatch or corrupted metadata — check KMS/age credentials and file integrity: %w", err)
}
return err
} Prevention
- Verify credentials (AWS_PROFILE, region, SOPS_AGE_KEY_FILE) before decrypting
- Never edit or reformat the sops metadata block in encrypted files
- Restore encrypted files only from trusted sources (git, versioned storage)
- Decrypt with the sops CLI first to confirm key access in new environments
When it happens
Trigger: Calling decrypt.Data/DataWithFormat on a file whose metadata MAC blob can't be decrypted: wrong or unavailable KMS/age/keyservice credentials yield a wrong data key; the sops metadata branch was edited or truncated; the file was modified (LastModified changed) in a way inconsistent with the stored MAC.
Common situations: Copying only the encrypted data branches between files without the matching metadata; automated formatters rewriting the YAML metadata timestamp; decrypting an old file after the KMS key was disabled or rotated; mismatched key groups after editing creation rules.
Related errors
- Failed to verify data integrity. expected mac %q, got %q
- Unknown datatype: %s
- Failed to read %q: %w
- Could not initialize AES GCM encryption cipher: %s
- Could not generate random bytes for IV: %s
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/993ccf5ae551aae9.
Report an issue: GitHub.