getsops/sops · error

failed to decrypt sops data key with Azure Key Vault key '%s

Error message

failed to decrypt sops data key with Azure Key Vault key '%s': %w

What it means

Raised in DecryptContext when the vault's Decrypt call (RSA-OAEP-256) fails for the given key name/version. This is the actual key-operation failure, with the Azure SDK error wrapped giving the precise reason.

Source

Thrown at azkv/keysource.go:287

	rawEncryptedKey, err := base64.RawURLEncoding.DecodeString(key.EncryptedKey)
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Decryption failed")
		return nil, fmt.Errorf("failed to base64 decode Azure Key Vault encrypted key: %w", err)
	}

	c, err := azkeys.NewClient(key.VaultURL, token, key.clientOptions)
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Decryption failed")
		return nil, fmt.Errorf("failed to construct Azure Key Vault client to decrypt data: %w", err)
	}

	resp, err := c.Decrypt(ctx, key.Name, key.Version, azkeys.KeyOperationParameters{
		Algorithm: to.Ptr(azkeys.EncryptionAlgorithmRSAOAEP256),
		Value:     rawEncryptedKey,
	}, nil)
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Decryption failed")
		return nil, fmt.Errorf("failed to decrypt sops data key with Azure Key Vault key '%s': %w", key.ToString(), err)
	}
	log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Decryption succeeded")
	return resp.KeyOperationResult.Result, nil
}

// NeedsRotation returns whether the data key needs to be rotated or not.
func (key *MasterKey) NeedsRotation() bool {
	return time.Since(key.CreationDate) > (azkvTTL)
}

// ToString converts the key to a string representation.
func (key *MasterKey) ToString() string {
	return fmt.Sprintf("%s/keys/%s/%s", key.VaultURL, key.Name, key.Version)
}

// ToMap converts the MasterKey to a map for serialization purposes.
func (key MasterKey) ToMap() map[string]interface{} {
	out := make(map[string]interface{})

View on GitHub (pinned to 13442bb981)

Solutions

  1. Confirm the key name/version in config matches the key that originally encrypted the file; re-encrypt if the key was rotated or purged
  2. Grant the identity Key Vault Crypto User (or 'decrypt' permission) on the vault
  3. Recover a soft-deleted key via `az keyvault key recover` if it was recently deleted
  4. Verify `az keyvault key decrypt` style access works with the same credentials to isolate auth vs key-state issues

Example fix

// before
azure_kv:
  - vault_url: https://oldvault.vault.azure.net/
    key: oldkey  # key purged after rotation
// after
azure_kv:
  - vault_url: https://myvault.vault.azure.net/
    key: currentkey
# then: sops --rotate-roles -i file.yaml  (or re-encrypt with the new key)
Defensive patterns

Strategy: retry

Validate before calling

// confirm decrypt permission and key existence first
az keyvault key show --vault-name <vault> --name <key>
az role assignment list --assignee <principal> --scope <vault-resource-id>  # expect Key Vault Crypto User

Try / catch

if err := masterKey.Decrypt(); err != nil {
	var azErr *azcore.ResponseError
	if errors.As(err, &azErr) {
		switch azErr.ErrorCode {
		case "KeyNotFound", "ObjectNotEnabledInKeyVault":
			// recover soft-deleted key or rotate: sops -r -i file.yaml
		case "Forbidden":
			// grant decrypt permission / Crypto User role
		}
	}
	return err
}

Prevention

When it happens

Trigger: Calling Decrypt where c.Decrypt errors: key deleted/rotated so the stored encrypted key was wrapped by a different key version, identity lacks the 'decrypt' permission, wrong key name in config, vault unreachable.

Common situations: Key was rotated or purged after the file was encrypted, service principal missing 'decrypt' access policy / Key Vault Crypto User role, using a different vault than the one that encrypted the file, key disabled.

Related errors


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