getsops/sops · error
failed to decrypt sops data key with GCP KMS key: %w
Error message
failed to decrypt sops data key with GCP KMS key: %w
What it means
The kms.Decrypt RPC failed inside DecryptContext after a successful client creation and base64 decoding of the stored ciphertext. Almost always an IAM/permission or key-state problem, since the ciphertext came from the encrypted SOPS file.
Source
Thrown at gcpkms/keysource.go:255
}
}()
// NB: this is for compatibility with SOPS <=3.8.x. The previous GCP KMS
// client used to work with base64 encoded strings.
decodedCipher, err := base64.StdEncoding.DecodeString(string(key.EncryptedDataKey()))
if err != nil {
log.WithField("resourceID", key.ResourceID).Info("Decryption failed")
return nil, err
}
req := &kmspb.DecryptRequest{
Name: key.ResourceID,
Ciphertext: decodedCipher,
}
resp, err := service.Decrypt(ctx, req)
if err != nil {
log.WithField("resourceID", key.ResourceID).Info("Decryption failed")
return nil, fmt.Errorf("failed to decrypt sops data key with GCP KMS key: %w", err)
}
log.WithField("resourceID", key.ResourceID).Info("Decryption succeeded")
return resp.Plaintext, nil
}
// NeedsRotation returns whether the data key needs to be rotated or not.
func (key *MasterKey) NeedsRotation() bool {
return time.Since(key.CreationDate) > (gcpkmsTTL)
}
// ToString converts the key to a string representation.
func (key *MasterKey) ToString() string {
return key.ResourceID
}
// ToMap converts the MasterKey to a map for serialization purposes.
func (key MasterKey) ToMap() map[string]interface{} {View on GitHub (pinned to 13442bb981)
Solutions
- Check the wrapped API error: grant roles/cloudkms.cryptoKeyDecrypter for 403.
- Ensure the ResourceID in the .sops.yaml / file metadata still points to the existing, ENABLED key.
- Run `gcloud auth list` / re-authenticate (`gcloud auth application-default login`) if using user credentials.
- Re-encrypt the file with the correct key if the key was destroyed.
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: gcloud kms keys describe KEY ... confirm ENABLED and that // the decrypting identity holds roles/cloudkms.cryptoKeyDecrypter.
Type guard
null
Try / catch
plaintext, err := key.DecryptContext(ctx)
if err != nil {
if strings.Contains(err.Error(), "failed to decrypt sops data key") {
// check IAM decrypter role / key state / correct ResourceID
}
return err
} Prevention
- Use the same identity (or a group with both encrypter+decrypter roles) for encrypt and decrypt.
- When rotating keys, re-encrypt files before destroying old keys.
- Verify ResourceID changes in .sops.yaml are intentional.
When it happens
Trigger: service.Decrypt(ctx, req) errors during MasterKey.DecryptContext — identity lacks roles/cloudkms.cryptoKeyDecrypter, key disabled/destroyed, or ciphertext was produced by a different key than ResourceID points to.
Common situations: Rotated the key or changed project and the file still references the old key resource; decryption identity differs from encryption identity and lacks the decrypter role; running `sops -d` locally with a different gcloud account.
Related errors
- failed to encrypt sops data key with GCP KMS key: %w
- cannot create GCP KMS service: %w
- no valid resource ID found in %q
- failed to decrypt sops data key with HuaweiCloud KMS: %w
- decryption response missing plaintext
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/e7406a2905487438.
Report an issue: GitHub.