getsops/sops · error

failed to construct Azure Key Vault client to encrypt data:

Error message

failed to construct Azure Key Vault client to encrypt data: %w

What it means

EncryptContext builds an azkeys client to perform the encrypt operation. This error means azkeys.NewClient failed, indicating an invalid VaultURL or client options rather than an Azure-side problem.

Source

Thrown at azkv/keysource.go:215

	key.Version = kdetail.Key.KID.Version()

	log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Version fetch succeeded")
	return nil
}

// EncryptContext takes a SOPS data key, encrypts it with Azure Key Vault, and stores
// the result in the EncryptedKey field.
func (key *MasterKey) EncryptContext(ctx context.Context, dataKey []byte) error {
	token, err := key.getTokenCredential()
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
		return fmt.Errorf("failed to get Azure token credential to encrypt data: %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("Encryption failed")
		return fmt.Errorf("failed to construct Azure Key Vault client to encrypt data: %w", err)
	}

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

	encodedEncryptedKey := base64.RawURLEncoding.EncodeToString(resp.KeyOperationResult.Result)
	key.SetEncryptedDataKey([]byte(encodedEncryptedKey))
	log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption succeeded")
	return nil
}

// EncryptedDataKey returns the encrypted data key this master key holds.

View on GitHub (pinned to 13442bb981)

Solutions

  1. Verify the vault URL is a complete https URL: https://<vault>.vault.azure.net
  2. Re-generate the encrypted file with a correctly formed azure_kv URL rather than hand-editing metadata
  3. Inspect key.clientOptions for custom proxy/transport settings that could invalidate the client
  4. Upgrade sops and its azure-sdk-for-go dependencies to the latest versions

Example fix

// before
azure_kv: "vault.azure.net/keys/k1"
// after
azure_kv: "https://myvault.vault.azure.net/keys/k1"
Defensive patterns

Strategy: validation

Validate before calling

if key.VaultURL == "" || !strings.HasPrefix(key.VaultURL, "https://") {
    return fmt.Errorf("cannot encrypt: invalid vault URL %q", key.VaultURL)
}
if _, err := url.Parse(key.VaultURL); err != nil {
    return fmt.Errorf("unparseable vault URL: %w", err)
}

Type guard

func hasValidVaultURL(key *azkv.MasterKey) bool {
    u, err := url.Parse(key.VaultURL)
    return key.VaultURL != "" && err == nil && u.Scheme == "https" && u.Host != ""
}

Try / catch

err := key.Encrypt(dataKey)
if strings.Contains(err.Error(), "failed to construct Azure Key Vault client to encrypt data") {
    return fmt.Errorf("vault URL in metadata is invalid; re-encrypt with a correct azure_kv URL: %w", err)
}

Prevention

When it happens

Trigger: EncryptContext calls azkeys.NewClient(key.VaultURL, token, key.clientOptions) and the SDK errors because key.VaultURL is empty or not a valid absolute https URL (e.g. from a malformed azure_kv entry in .sops.yaml).

Common situations: Malformed key URL stored in the sops metadata; hand-edited .sops.yaml dropping the scheme; SDK/clientOptions misconfiguration; very old sops with incompatible Azure SDK versions.

Related errors


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