{"record":{"id":"06237381b7757461","repo":"OrchardCMS/OrchardCore","slug":"the-orchardcore-signalr-azure-and-orchardcore-signalr-redis","errorCode":null,"errorMessage":"The 'OrchardCore.SignalR.Azure' and 'OrchardCore.SignalR.Redis' features cannot be enabled together.","messagePattern":"The 'OrchardCore\\.SignalR\\.Azure' and 'OrchardCore\\.SignalR\\.Redis' features cannot be enabled together\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore.Modules/OrchardCore.SignalR.Azure/Startup.cs","lineNumber":87,"sourceCode":"    internal static string CreateApplicationName(string applicationName, string tenantName)\n    {\n        if (string.IsNullOrWhiteSpace(applicationName))\n        {\n            applicationName = DefaultApplicationName;\n        }\n\n        var tenantHash = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(tenantName)));\n\n        return $\"{applicationName}_{tenantHash}\";\n    }\n\n    private static void EnsureNoBackplaneIsRegistered(IServiceCollection services)\n    {\n        if (services.Any(descriptor =>\n            descriptor.IsKeyedService &&\n            string.Equals(descriptor.ServiceKey as string, BackplaneRegistrationKey, StringComparison.Ordinal)))\n        {\n            throw new InvalidOperationException(\n                $\"The '{AzureBackplaneFeature}' and '{RedisBackplaneFeature}' features cannot be enabled together.\");\n        }\n\n        services.AddKeyedSingleton<object>(BackplaneRegistrationKey, new object());\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":94,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore.Modules/OrchardCore.SignalR.Azure/Startup.cs#L69-L94","documentation":"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.","triggerScenarios":"Enabling both the OrchardCore.SignalR.Azure and OrchardCore.SignalR.Redis features on the same tenant; a recipe or setup enabling both features at once.","commonSituations":"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.","solutions":["Disable one of the two features (OrchardCore.SignalR.Azure or OrchardCore.SignalR.Redis) so only a single backplane remains enabled.","Fix the setup/recipe JSON to not enable both features in the same tenant.","If migrating backplanes, disable one feature and restart before enabling the other."],"exampleFix":"// recipe before\n\"features\": [\"OrchardCore.SignalR.Redis\", \"OrchardCore.SignalR.Azure\"]\n// recipe after\n\"features\": [\"OrchardCore.SignalR.Redis\"]","handlingStrategy":"validation","validationCode":"// before enabling a backplane feature\nvar enabled = new[] { \"OrchardCore.SignalR.Azure\", \"OrchardCore.SignalR.Redis\" }\n    .Count(f => features.Contains(f));\nif (enabled > 1) throw new InvalidOperationException(\"Enable only one SignalR backplane feature per tenant.\");","typeGuard":"const singleBackplane = (features) => ['OrchardCore.SignalR.Azure','OrchardCore.SignalR.Redis'].filter(f => features.includes(f)).length <= 1;","tryCatchPattern":"try {\n  await enableFeatureAsync(\"OrchardCore.SignalR.Azure\");\n} catch (InvalidOperationException ex) when (ex.Message.Contains(\"cannot be enabled together\")) {\n  logger.LogWarning(\"Disable the Redis backplane first.\");\n}","preventionTips":["Audit tenant/recipe feature lists to ensure only one backplane feature.","Document the chosen backplane per environment.","Validate recipes in CI before provisioning tenants."],"tags":["signalr","backplane","configuration","conflicting-features"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}