getsops/sops · error

failed to get Azure token credential to retrieve key version

Error message

failed to get Azure token credential to retrieve key version: %w

What it means

ensureKeyHasVersion resolves the latest version of a key when the URL omitted a key version. It first needs a DefaultAzureCredential-style token credential; this error means obtaining that credential failed, so the key version cannot be looked up.

Source

Thrown at azkv/keysource.go:183

// Encrypt takes a SOPS data key, encrypts it with Azure Key Vault, and stores
// the result in the EncryptedKey field.
//
// Consider using EncryptContext instead.
func (key *MasterKey) Encrypt(dataKey []byte) error {
	return key.EncryptContext(context.Background(), dataKey)
}

func (key *MasterKey) ensureKeyHasVersion(ctx context.Context) error {
	if key.Version != "" {
		// Nothing to do
		return nil
	}

	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 retrieve key version: %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 retrieve key version: %w", err)
	}

	kdetail, err := c.GetKey(ctx, key.Name, key.Version, nil)
	if err != nil {
		log.WithFields(logrus.Fields{"key": key.Name, "version": key.Version}).Info("Encryption failed")
		return fmt.Errorf("failed to fetch Azure Key to retrieve key version: %w", err)
	}
	key.Version = kdetail.Key.KID.Version()

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

View on GitHub (pinned to 13442bb981)

Solutions

  1. Authenticate locally with az login, or set AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET for a service principal
  2. In Azure-hosted environments, ensure the resource has a managed identity enabled
  3. Verify AZURE_CLIENT_SECRET/AZURE_CLIENT_CERTIFICATE_PATH values are current and not expired
  4. Run az account get-access-token to confirm the ambient credential works before running sops

Example fix

// before
export SOPS_AZURE_KEY_VAULT_URL=https://myvault.vault.azure.net/keys/k  # no creds set
// after
export AZURE_TENANT_ID=... AZURE_CLIENT_ID=... AZURE_CLIENT_SECRET=...
export SOPS_AZURE_KEY_VAULT_URL=https://myvault.vault.azure.net/keys/k
Defensive patterns

Strategy: try-catch

Validate before calling

cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
    return fmt.Errorf("no Azure credential available: %w (run 'az login' or set AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET)", err)
}
tok, err := cred.GetToken(context.Background(), policy.TokenRequestOptions{Scopes: []string{"https://vault.azure.net/.default"}})
if err != nil { return fmt.Errorf("Azure token acquisition failed: %w", err) }
_ = tok

Try / catch

err := sopsRun(...)
var credErr *azidentity.CredentialUnavailableError
if errors.As(err, &credErr) || strings.Contains(err.Error(), "failed to get Azure token credential") {
    return fmt.Errorf("authenticate to Azure first (az login or service principal env vars): %w", err)
}

Prevention

When it happens

Trigger: ensureKeyHasVersion (called from NewMasterKeyFromURL) calls key.getTokenCredential() and it errors — typically azidentity.NewDefaultAzureCredential failing because no Azure authentication source is configured.

Common situations: Missing AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRET; not logged in with az login; running in CI without a managed identity; AZURE_AUTHORITY_HOST misconfigured; azidentity environment variables pointing to an invalid service principal.

Related errors


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