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

  1. Check the wrapped API error: grant roles/cloudkms.cryptoKeyDecrypter for 403.
  2. Ensure the ResourceID in the .sops.yaml / file metadata still points to the existing, ENABLED key.
  3. Run `gcloud auth list` / re-authenticate (`gcloud auth application-default login`) if using user credentials.
  4. 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

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


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