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

  1. Confirm you can decrypt with the CLI (sops -d file) to isolate whether credentials or the file are at fault
  2. Check KMS/age credentials: AWS_PROFILE, AWS region, age identity file (SOPS_AGE_KEY_FILE), key groups present
  3. 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
  4. 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

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


AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01). Data as JSON: /api/errors/993ccf5ae551aae9. Report an issue: GitHub.