elsa-workflows/elsa-core · error · InvalidOperationException

The configured secret binding is not active.

Error message

The configured secret binding is not active.

What it means

ResolveAsync requires the secret to be in SecretStatus.Active and to have a LatestActiveVersion. Secrets in other statuses (e.g. disabled, pending, revoked) or without an active version cannot supply usable material and cause this error.

Solutions

  1. Re-enable/reactivate the secret or publish a new active version via StageAsync and CAS publish
  2. Check the secret's status via GetStateAsync before resolving and surface a clear configuration error to the user
  3. Fix the rotation process so it always publishes a new active version before retiring the old one

Example fix

// before
var resolved = await resolver.ResolveAsync(binding);
// after
var state = await resolver.GetStateAsync(binding);
if (state is { Status: SecretStatus.Active, LatestActiveVersion: not null }) {
    var resolved = await resolver.ResolveAsync(binding);
} else {
    // re-stage and publish a new active secret version
}
Defensive patterns

Strategy: try-catch

Validate before calling

var state = await resolver.GetStateAsync(binding);
if (!state.IsActive) throw new InvalidOperationException("Secret is not active; rotate or re-enable it before use.");

Type guard

bool IsActiveSecret(SecretBinding b) => b is { Status: SecretStatus.Active, LatestActiveVersion: not null };

Try / catch

try { return await resolver.ResolveAsync(binding); }
catch (InvalidOperationException ex) when (ex.Message.Contains("not active"))
{ throw new ConfigurationException("The referenced secret is inactive; rotate or re-enable it.", ex); }

Prevention

When it happens

Trigger: Calling ResolveAsync when the referenced secret's Status is not Active, or its LatestActiveVersion is null — e.g. the secret was disabled, all versions were superseded/revoked, or the secret was created without any active version.

Common situations: A secret disabled by an administrator or by security policy; rotation pipelines that left no active version; secrets expired after a rotation window passed.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of elsa-workflows/elsa-core@fe9217bdfa (2026-09-13). Data as JSON: /api/errors/a2c968f520bd821c. Report an issue: GitHub.

Appendix: source

Thrown at src/modules/Elsa.ExternalAuthentication.Secrets/Services/ElsaSecretBindingResolver.cs:75

            return new(false, false);

        var configured = secret is { Status: SecretStatus.Active, LatestActiveVersion: not null };
        if (!configured || !IsCompatible(secret, binding))
            return new(configured, false);

        var test = await secretManager.TestAsync(secret.Name, cancellationToken);
        return new(true, test.Succeeded);
    }

    public async ValueTask<ResolvedSecretBinding> ResolveAsync(SecretBinding binding, CancellationToken cancellationToken = default)
    {
        EnsureResolverType(binding);
        var secret = await secretManager.GetAsync(binding.Reference, cancellationToken)
            ?? throw new InvalidOperationException("The configured secret binding could not be resolved.");
        if (!IsCompatible(secret, binding))
            throw new InvalidOperationException("The configured secret binding is incompatible with the required type or scope.");
        if (secret is not { Status: SecretStatus.Active, LatestActiveVersion: { } version })
            throw new InvalidOperationException("The configured secret binding is not active.");

        var payload = await secretManager.ResolvePayloadAsync(secret, cancellationToken);
        if (payload.Value is null)
            throw new InvalidOperationException("The configured secret binding could not be resolved.");

        var fingerprint = handleHasher.Hash($"{ResolverType}:{secret.Id}:{version.Version}:{version.CreatedAt.ToUnixTimeMilliseconds()}");
        return new(new(payload.Value), fingerprint);
    }

    private static void EnsureResolverType(SecretBinding binding)
    {
        if (!string.Equals(binding.ResolverType, ResolverType, StringComparison.Ordinal))
            throw new InvalidOperationException("The secret binding selects a different resolver type.");
        if (string.IsNullOrWhiteSpace(binding.Reference))
            throw new InvalidOperationException("The secret binding reference is required.");
    }

    private static bool IsCompatible(Secret secret, SecretBinding binding) =>

View on GitHub (pinned to fe9217bdfa)