OrchardCMS/OrchardCore · error · InvalidOperationException

The 'OrchardCore.SignalR.Azure' and…

Error message

The 'OrchardCore.SignalR.Azure' and 'OrchardCore.SignalR.Redis' features cannot be enabled together.

What it means

The SignalR.Azure module registers an Azure SignalR backplane and refuses to start if another backplane (SignalR.Redis) was already registered in the same service collection. It detects this via a keyed singleton marker registered by whichever backplane feature initializes first and throws InvalidOperationException.

Solutions

  1. Disable one of the two features (OrchardCore.SignalR.Azure or OrchardCore.SignalR.Redis) so only a single backplane remains enabled.
  2. Fix the setup/recipe JSON to not enable both features in the same tenant.
  3. If migrating backplanes, disable one feature and restart before enabling the other.

Example fix

// recipe before
"features": ["OrchardCore.SignalR.Redis", "OrchardCore.SignalR.Azure"]
// recipe after
"features": ["OrchardCore.SignalR.Redis"]
Defensive patterns

Strategy: validation

Validate before calling

// before enabling a backplane feature
var enabled = new[] { "OrchardCore.SignalR.Azure", "OrchardCore.SignalR.Redis" }
    .Count(f => features.Contains(f));
if (enabled > 1) throw new InvalidOperationException("Enable only one SignalR backplane feature per tenant.");

Type guard

const singleBackplane = (features) => ['OrchardCore.SignalR.Azure','OrchardCore.SignalR.Redis'].filter(f => features.includes(f)).length <= 1;

Try / catch

try {
  await enableFeatureAsync("OrchardCore.SignalR.Azure");
} catch (InvalidOperationException ex) when (ex.Message.Contains("cannot be enabled together")) {
  logger.LogWarning("Disable the Redis backplane first.");
}

Prevention

When it happens

Trigger: Enabling both the OrchardCore.SignalR.Azure and OrchardCore.SignalR.Redis features on the same tenant; a recipe or setup enabling both features at once.

Common situations: Tenant configured with Redis backplane then someone enables Azure SignalR feature from admin UI; a recipe combining both features by accident; copying feature lists between tenants.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/06237381b7757461. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.SignalR.Azure/Startup.cs:87

    internal static string CreateApplicationName(string applicationName, string tenantName)
    {
        if (string.IsNullOrWhiteSpace(applicationName))
        {
            applicationName = DefaultApplicationName;
        }

        var tenantHash = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(tenantName)));

        return $"{applicationName}_{tenantHash}";
    }

    private static void EnsureNoBackplaneIsRegistered(IServiceCollection services)
    {
        if (services.Any(descriptor =>
            descriptor.IsKeyedService &&
            string.Equals(descriptor.ServiceKey as string, BackplaneRegistrationKey, StringComparison.Ordinal)))
        {
            throw new InvalidOperationException(
                $"The '{AzureBackplaneFeature}' and '{RedisBackplaneFeature}' features cannot be enabled together.");
        }

        services.AddKeyedSingleton<object>(BackplaneRegistrationKey, new object());
    }
}

View on GitHub (pinned to 4306c0717f)