getsops/sops · error

failed to encrypt sops data key with GCP KMS key: %w

Error message

failed to encrypt sops data key with GCP KMS key: %w

What it means

The GCP KMS client was created successfully, but the kms.Encrypt RPC for the SOPS data key failed. SOPS wraps the Google API error, which typically indicates IAM permission, key state, or project/location mismatch issues.

Source

Thrown at gcpkms/keysource.go:189

	service, err := key.newKMSClient(ctx)
	if err != nil {
		log.WithField("resourceID", key.ResourceID).Info("Encryption failed")
		return fmt.Errorf("cannot create GCP KMS service: %w", err)
	}
	defer func() {
		if err := service.Close(); err != nil {
			log.Error("failed to close GCP KMS client connection")
		}
	}()

	req := &kmspb.EncryptRequest{
		Name:      key.ResourceID,
		Plaintext: dataKey,
	}
	resp, err := service.Encrypt(ctx, req)
	if err != nil {
		log.WithField("resourceID", key.ResourceID).Info("Encryption failed")
		return fmt.Errorf("failed to encrypt sops data key with GCP KMS key: %w", err)
	}
	// NB: base64 encoding is for compatibility with SOPS <=3.8.x.
	// The previous GCP KMS client used to work with base64 encoded
	// strings.
	key.EncryptedKey = base64.StdEncoding.EncodeToString(resp.Ciphertext)
	log.WithField("resourceID", key.ResourceID).Info("Encryption succeeded")
	return nil
}

// SetEncryptedDataKey sets the encrypted data key for this master key.
func (key *MasterKey) SetEncryptedDataKey(enc []byte) {
	key.EncryptedKey = string(enc)
}

// EncryptedDataKey returns the encrypted data key this master key holds.
func (key *MasterKey) EncryptedDataKey() []byte {
	return []byte(key.EncryptedKey)
}

View on GitHub (pinned to 13442bb981)

Solutions

  1. Read the wrapped Google API status: if 403, grant roles/cloudkms.cryptoKeyEncrypter to the identity.
  2. Verify the key exists and is ENABLED via `gcloud kms keys describe`.
  3. Check the ResourceID region/location matches the actual key location.
  4. For transient 5xx/429 errors, retry with backoff.

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check IAM: gcloud kms keys describe KEY --location L --keyring R --project P
// and confirm the identity has roles/cloudkms.cryptoKeyEncrypter and key state ENABLED.

Type guard

null

Try / catch

if err := key.EncryptContext(ctx, dataKey); err != nil {
    var apiErr *apierror.APIError
    if errors.As(err.Unwrap(), &apiErr) && apiErr.Code() == 5 {
        // retry with backoff for transient failures
    }
    return err
}

Prevention

When it happens

Trigger: service.Encrypt(ctx, req) returns a non-nil error during MasterKey.EncryptContext — e.g. the caller lacks roles/cloudkms.cryptoKeyEncrypter on the key, the key is disabled/destroyed, or the resource ID names a nonexistent key.

Common situations: Service account missing cloudkms.cryptoKeyEncrypter/get; key scheduled for destruction; typo in cryptoKey name; regional key accessed from wrong location; quota or transient 5xx from Google API.

Related errors


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