{"record":{"id":"5faed7544e107d27","repo":"getsops/sops","slug":"failed-to-decrypt-sops-data-key-with-azure-key-vau","errorCode":null,"errorMessage":"failed to decrypt sops data key with Azure Key Vault key '%s': %w","messagePattern":"failed to decrypt sops data key with Azure Key Vault key '(.+?)': %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"azkv/keysource.go","lineNumber":287,"sourceCode":"\trawEncryptedKey, err := base64.RawURLEncoding.DecodeString(key.EncryptedKey)\n\tif err != nil {\n\t\tlog.WithFields(logrus.Fields{\"key\": key.Name, \"version\": key.Version}).Info(\"Decryption failed\")\n\t\treturn nil, fmt.Errorf(\"failed to base64 decode Azure Key Vault encrypted key: %w\", err)\n\t}\n\n\tc, err := azkeys.NewClient(key.VaultURL, token, key.clientOptions)\n\tif err != nil {\n\t\tlog.WithFields(logrus.Fields{\"key\": key.Name, \"version\": key.Version}).Info(\"Decryption failed\")\n\t\treturn nil, fmt.Errorf(\"failed to construct Azure Key Vault client to decrypt data: %w\", err)\n\t}\n\n\tresp, err := c.Decrypt(ctx, key.Name, key.Version, azkeys.KeyOperationParameters{\n\t\tAlgorithm: to.Ptr(azkeys.EncryptionAlgorithmRSAOAEP256),\n\t\tValue:     rawEncryptedKey,\n\t}, nil)\n\tif err != nil {\n\t\tlog.WithFields(logrus.Fields{\"key\": key.Name, \"version\": key.Version}).Info(\"Decryption failed\")\n\t\treturn nil, fmt.Errorf(\"failed to decrypt sops data key with Azure Key Vault key '%s': %w\", key.ToString(), err)\n\t}\n\tlog.WithFields(logrus.Fields{\"key\": key.Name, \"version\": key.Version}).Info(\"Decryption succeeded\")\n\treturn resp.KeyOperationResult.Result, nil\n}\n\n// NeedsRotation returns whether the data key needs to be rotated or not.\nfunc (key *MasterKey) NeedsRotation() bool {\n\treturn time.Since(key.CreationDate) > (azkvTTL)\n}\n\n// ToString converts the key to a string representation.\nfunc (key *MasterKey) ToString() string {\n\treturn fmt.Sprintf(\"%s/keys/%s/%s\", key.VaultURL, key.Name, key.Version)\n}\n\n// ToMap converts the MasterKey to a map for serialization purposes.\nfunc (key MasterKey) ToMap() map[string]interface{} {\n\tout := make(map[string]interface{})","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/azkv/keysource.go#L269-L305","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the key name/version in config matches the key that originally encrypted the file; re-encrypt if the key was rotated or purged","Grant the identity Key Vault Crypto User (or 'decrypt' permission) on the vault","Recover a soft-deleted key via `az keyvault key recover` if it was recently deleted","Verify `az keyvault key decrypt` style access works with the same credentials to isolate auth vs key-state issues"],"exampleFix":"// before\nazure_kv:\n  - vault_url: https://oldvault.vault.azure.net/\n    key: oldkey  # key purged after rotation\n// after\nazure_kv:\n  - vault_url: https://myvault.vault.azure.net/\n    key: currentkey\n# then: sops --rotate-roles -i file.yaml  (or re-encrypt with the new key)","handlingStrategy":"retry","validationCode":"// confirm decrypt permission and key existence first\naz keyvault key show --vault-name <vault> --name <key>\naz role assignment list --assignee <principal> --scope <vault-resource-id>  # expect Key Vault Crypto User","typeGuard":null,"tryCatchPattern":"if err := masterKey.Decrypt(); err != nil {\n\tvar azErr *azcore.ResponseError\n\tif errors.As(err, &azErr) {\n\t\tswitch azErr.ErrorCode {\n\t\tcase \"KeyNotFound\", \"ObjectNotEnabledInKeyVault\":\n\t\t\t// recover soft-deleted key or rotate: sops -r -i file.yaml\n\t\tcase \"Forbidden\":\n\t\t\t// grant decrypt permission / Crypto User role\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Never purge or hard-delete vault keys referenced by existing encrypted files","Before rotating a key, re-encrypt all files (`sops -r -i`) with the new key version","Grant Key Vault Crypto User role to all identities that decrypt sops files","Keep soft-delete and purge-protection enabled on the vault"],"tags":["azure","key-vault","decryption","permissions"],"backgroundTag":"azure-key-vault-decrypt-denied","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}