{"record":{"id":"4efd439c4edc0fe0","repo":"HangfireIO/Hangfire","slug":"current-owin-environment-does-not-contain-an-insta","errorCode":null,"errorMessage":"Current OWIN environment does not contain an instance of the `CancellationToken` class neither under `host.OnAppDisposing`, nor `server.OnDispose` key.\r\nPlease use another OWIN host or create an instance of the `BackgroundJobServer` class manually.","messagePattern":"Current OWIN environment does not contain an instance of the `CancellationToken` class neither under `host\\.OnAppDisposing`, nor `server\\.OnDispose` key\\.\r\nPlease use another OWIN host or create an instance of the `BackgroundJobServer` class manually\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Hangfire.Core/AppBuilderExtensions.cs","lineNumber":333,"sourceCode":"            [NotNull] this IAppBuilder builder,\n            [NotNull] IBackgroundProcessingServer server)\n        {\n            if (builder == null) throw new ArgumentNullException(nameof(builder));\n            if (server == null) throw new ArgumentNullException(nameof(server));\n\n            Servers.TryAdd(server, null);\n\n            var context = new OwinContext(builder.Properties);\n            var token = context.Get<CancellationToken>(\"host.OnAppDisposing\");\n            if (token == default(CancellationToken))\n            {\n                // https://github.com/owin/owin/issues/27\n                token = context.Get<CancellationToken>(\"server.OnDispose\");\n            }\n\n            if (token == default(CancellationToken))\n            {\n                throw new InvalidOperationException(\n                    \"Current OWIN environment does not contain an instance of the `CancellationToken` class neither under `host.OnAppDisposing`, nor `server.OnDispose` key.\\r\\n\"\n                    + \"Please use another OWIN host or create an instance of the `BackgroundJobServer` class manually.\");\n            }\n\n            token.Register(OnAppDisposing, server);\n            return builder;\n        }\n\n        private static void OnAppDisposing(object state)\n        {\n            var logger = LogProvider.GetLogger(typeof(AppBuilderExtensions));\n            logger.Info(\"Web application is shutting down via OWIN's host.OnAppDisposing callback.\");\n\n            ((IDisposable) state).Dispose();\n\n            if (state is IBackgroundProcessingServer server)\n                Servers.TryRemove(server, out _);\n        }","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/AppBuilderExtensions.cs#L315-L351","documentation":"When starting a BackgroundJobServer via the OWIN AppBuilderExtensions pipeline, Hangfire looks for a cancellation token under the OWIN keys 'host.OnAppDisposing' or 'server.OnDispose' so it can shut the server down cleanly when the host stops. If neither key yields a CancellationToken, an InvalidOperationException is thrown because Hangfire cannot register its shutdown callback. The exception explicitly tells you to use a different OWIN host or to instantiate BackgroundJobServer manually.","triggerScenarios":"Calling appBuilder.UseHangfireServer(...) under an OWIN host that does not populate 'host.OnAppDisposing' or 'server.OnDispose' in its environment dictionary — e.g., a minimal/custom OWIN host, an in-memory test host, or certain non-Microsoft hosts.","commonSituations":"Using a third-party or self-built OWIN host that omits shutdown-token registration; running Hangfire OWIN integration inside a test harness (OwinTestServer / Microsoft.Owin.Testing) that does not expose a shutdown token; upgrading an OWIN host that dropped the legacy key.","solutions":["Switch to a host that provides the shutdown token — Microsoft.Owin.Host.SystemWeb (IIS) or Microsoft.Owin.Host.HttpListener both populate host.OnAppDisposing.","If you control the OWIN environment dictionary, add 'host.OnAppDisposing' (a CancellationToken) to builder.Properties before calling UseHangfireServer.","Bypass the OWIN extension and create BackgroundJobServer manually with your own CancellationToken/WebHost stop hook.","For ASP.NET Core apps, use services.AddHangfireServer() instead of the OWIN pipeline."],"exampleFix":"// before\napp.UseHangfireServer(); // throws under minimal OWIN host\n\n// after (manual server with own token)\nvar server = new BackgroundJobServer();\n// dispose 'server' on application shutdown\n\n// or for ASP.NET Core\nservices.AddHangfire(config => config.UseXXXStorage());\nservices.AddHangfireServer();","handlingStrategy":"fallback","validationCode":"var ctx = new OwinContext(builder.Properties);\nbool hasShutdownToken =\n    ctx.Get<CancellationToken>(\"host.OnAppDisposing\") != default ||\n    ctx.Get<CancellationToken>(\"server.OnDispose\") != default;\nif (!hasShutdownToken)\n{\n    // host does not support shutdown token; do not call UseHangfireServer\n}","typeGuard":"static bool OwinHostSupportsShutdown(IAppBuilder b)\n{\n    var ctx = new OwinContext(b.Properties);\n    return ctx.Get<CancellationToken>(\"host.OnAppDisposing\") != default(CancellationToken)\n        || ctx.Get<CancellationToken>(\"server.OnDispose\") != default(CancellationToken);\n}","tryCatchPattern":"try { app.UseHangfireServer(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"host.OnAppDisposing\"))\n{\n    // fall back to a manually created BackgroundJobServer\n}","preventionTips":["Use Microsoft.Owin.Host.SystemWeb or HttpListener hosts which provide the shutdown token.","For ASP.NET Core, prefer services.AddHangfireServer() over the OWIN pipeline.","If you control the OWIN environment, add 'host.OnAppDisposing' to builder.Properties."],"tags":["owin","hosting","shutdown","cancellation-token","invalidoperationexception"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}