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 BaseHashCookieSessionAffinityPolicy.FindAffinitizedDestinations when `config.Enabled` is not true. Read-side counterpart to error 48 for hash-cookie policies; includes `cluster.ClusterId` in the message for diagnostics.

Source

Thrown at src/ReverseProxy/SessionAffinity/BaseHashCookieSessionAffinityPolicy.cs:58

            return;
        }

        // Affinity key is set on the response only if it's a new affinity.
        if (!context.Items.ContainsKey(AffinityKeyId))
        {
            var affinityKey = GetDestinationHash(destination);
            var affinityCookieOptions = AffinityHelpers.CreateCookieOptions(config.Cookie, context.Request.IsHttps, _timeProvider);

            // CodeQL [SM02373] - Whether CookieOptions.Secure is used depends on YARP configuration, and session affinity may be used in non-HTTPS setups. Hash-based affinity policies do not intend to provide privacy protection. See https://learn.microsoft.com/aspnet/core/fundamentals/servers/yarp/session-affinity#key-protection.
            context.Response.Cookies.Append(config.AffinityKeyName, affinityKey, affinityCookieOptions);
        }
    }

    public 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 affinityHash = context.Request.Cookies[config.AffinityKeyName];
        if (affinityHash is null)
        {
            return new(null, AffinityStatus.AffinityKeyNotSet);
        }

        foreach (var d in destinations)
        {
            var hashValue = GetDestinationHash(d);

            if (affinityHash == hashValue)
            {
                context.Items[AffinityKeyId] = affinityHash;
                return new(d, AffinityStatus.OK);
            }
        }

View on GitHub (pinned to bd11867bee)

Solutions

  1. Enable affinity on the cluster: `SessionAffinity.Enabled = true`.
  2. Ensure affinity lookup only runs against enabled clusters.
  3. Verify the ClusterState/SessionAffinityConfig pair is the intended one.

Example fix

// before
SessionAffinity = new SessionAffinityConfig { Policy = "HashCookie", AffinityKeyName = "Yarp.Affinity" }
// after
SessionAffinity = new SessionAffinityConfig { Enabled = true, Policy = "HashCookie", 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 called on a cluster whose SessionAffinityConfig.Enabled is false/null, with a hash-cookie policy in use.

Common situations: Hash-cookie affinity policy registered globally; some clusters do not enable affinity. Cluster config edited and `Enabled` lost.

Related errors


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