dotnet/yarp · error · InvalidOperationException

Session affinity is disabled for cluster {cluster.ClusterId}

Error message

Session affinity is disabled for cluster {cluster.ClusterId}.

What it means

Thrown by BaseEncryptedSessionAffinityPolicy.FindAffinitizedDestinations when `config.Enabled` is not true. This is the read-side counterpart to AffinitizeResponse: looking up an affinity key is only valid when affinity is enabled for the cluster. The message includes `cluster.ClusterId` for diagnostics.

Source

Thrown at src/ReverseProxy/SessionAffinity/BaseEncryptedSessionAffinityPolicy.cs:55

        if (context.RequestAborted.IsCancellationRequested)
        {
            // Avoid wasting time if the client is already gone.
            return;
        }

        // Affinity key is set on the response only if it's a new affinity.
        if (!context.Items.ContainsKey(AffinityKeyId))
        {
            var affinityKey = GetDestinationAffinityKey(destination);
            SetAffinityKey(context, cluster, config, affinityKey);
        }
    }

    public virtual AffinityResult FindAffinitizedDestinations(HttpContext context, ClusterState cluster, SessionAffinityConfig config, IReadOnlyList<DestinationState> destinations)
    {
        if (!config.Enabled.GetValueOrDefault())
        {
            throw new InvalidOperationException($"Session affinity is disabled for cluster {cluster.ClusterId}.");
        }

        var requestAffinityKey = GetRequestAffinityKey(context, cluster, config);

        if (requestAffinityKey.Key is null)
        {
            return new AffinityResult(null, requestAffinityKey.ExtractedSuccessfully ? AffinityStatus.AffinityKeyNotSet : AffinityStatus.AffinityKeyExtractionFailed);
        }

        IReadOnlyList<DestinationState>? matchingDestinations = null;
        if (destinations.Count > 0)
        {
            for (var i = 0; i < destinations.Count; i++)
            {
                // TODO: Add fast destination lookup by ID
                if (requestAffinityKey.Key.Equals(GetDestinationAffinityKey(destinations[i])))
                {
                    // It's allowed to affinitize a request to a pool of destinations to enable load-balancing among them.

View on GitHub (pinned to bd11867bee)

Solutions

  1. Enable affinity on the cluster: `SessionAffinity = new SessionAffinityConfig { Enabled = true, ... }`.
  2. Ensure the affinity middleware only runs for clusters with affinity enabled (YARP does this by default; custom wiring may not).
  3. Confirm the ClusterState passed in matches an affinity-enabled cluster.

Example fix

// before
var cfg = new SessionAffinityConfig { AffinityKeyName = "Yarp.Affinity" };
// after
var cfg = new SessionAffinityConfig { Enabled = true, AffinityKeyName = "Yarp.Affinity" };
Defensive patterns

Strategy: validation

Validate before calling

if (!config.Enabled.GetValueOrDefault())
    throw new InvalidOperationException("Enable SessionAffinity before FindAffinitizedDestinations.");

Type guard

static bool AffinityEnabled(SessionAffinityConfig? config) =>
    config is not null && config.Enabled.GetValueOrDefault();

Prevention

When it happens

Trigger: FindAffinitizedDestinations is called on a cluster whose SessionAffinityConfig.Enabled is false/null. Happens when the affinity middleware runs against a cluster that did not opt into affinity.

Common situations: Affinity middleware added globally but only some clusters enable affinity. Cluster config edited and `Enabled` dropped. Test calling FindAffinitizedDestinations on a default config.

Related errors


AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13). Data as JSON: /api/errors/630ff74a353dec7d. Report an issue: GitHub.