{"record":{"id":"6e4a3ab5e40e4518","repo":"HangfireIO/Hangfire","slug":"current-jobstorage-instance-has-not-been-initializ","errorCode":null,"errorMessage":"Current JobStorage instance has not been initialized yet. You must set it before using Hangfire Client or Server API. For .NET Core applications please call the `IServiceCollection.AddHangfire` extension method from Hangfire.NetCore or Hangfire.AspNetCore package depending on your application type when configuring the services and ensure service-based APIs are used instead of static ones, like `IBackgroundJobClient` instead of `BackgroundJob` and `IRecurringJobManager` instead of `RecurringJob`.","messagePattern":"Current JobStorage instance has not been initialized yet\\. You must set it before using Hangfire Client or Server API\\. For \\.NET Core applications please call the `IServiceCollection\\.AddHangfire` extension method from Hangfire\\.NetCore or Hangfire\\.AspNetCore package depending on your application type when configuring the services and ensure service-based APIs are used instead of static ones, like `IBackgroundJobClient` instead of `BackgroundJob` and `IRecurringJobManager` instead of `RecurringJob`\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Hangfire.Core/JobStorage.cs","lineNumber":42,"sourceCode":"\nnamespace Hangfire\n{\n    public abstract class JobStorage\n    {\n        private static readonly object LockObject = new object();\n        private static JobStorage _current;\n\n        private TimeSpan _jobExpirationTimeout = TimeSpan.FromDays(1);\n\n        public static JobStorage Current\n        {\n            get\n            {\n                lock (LockObject)\n                {\n                    if (_current == null)\n                    {\n                        throw new InvalidOperationException(\n                            \"Current JobStorage instance has not been initialized yet. You must set it before using Hangfire Client or Server API. \" +\n#if NET45 || NET46\n                            \"For NET Framework applications please use GlobalConfiguration.UseXXXStorage method, where XXX is the storage type, like `UseSqlServerStorage`.\"\n#else\n                            \"For .NET Core applications please call the `IServiceCollection.AddHangfire` extension method from Hangfire.NetCore or Hangfire.AspNetCore package depending on your application type when configuring the services and ensure service-based APIs are used instead of static ones, like `IBackgroundJobClient` instead of `BackgroundJob` and `IRecurringJobManager` instead of `RecurringJob`.\"\n#endif\n                            );\n                    }\n\n                    return _current;\n                }\n            }\n            set\n            {\n                lock (LockObject)\n                {\n                    _current = value;\n                }","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/JobStorage.cs#L24-L60","documentation":"Thrown by JobStorage.Current getter when no JobStorage has been initialized. This is the single most common startup error in Hangfire: the static Current property requires a storage backend (SQL Server, Redis, etc.) to be set before any client or server API is used.","triggerScenarios":"Accessing JobStorage.Current, or using static APIs like BackgroundJob.Enqueue(...) or RecurringJob.AddOrUpdate(...), before calling GlobalConfiguration.Configuration.UseXXXStorage(...). Also occurs in .NET Core when static APIs are used instead of service-based ones.","commonSituations":"Forgetting to register storage in Startup.ConfigureServices, using BackgroundJob.Enqueue() instead of IBackgroundJobClient in ASP.NET Core (where DI should provide the client), calling static APIs before app startup completes, or a storage registration that threw an exception silently.","solutions":["For .NET Framework: call GlobalConfiguration.Configuration.UseSqlServerStorage(connectionString) at application start","For .NET Core/ASP.NET Core: call services.AddHangfire(config => config.UseSqlServerStorage(connectionString)) in ConfigureServices","Use service-based APIs (IBackgroundJobClient, IRecurringJobManager) injected via DI instead of static ones","Verify the storage registration line actually executes (check for earlier exceptions in startup logs)"],"exampleFix":"// before (.NET Core)\nBackgroundJob.Enqueue(() => Console.WriteLine(\"hi\"));\n// throws: JobStorage.Current not initialized\n\n// after\n// In Startup.ConfigureServices:\nservices.AddHangfire(config =>\n    config.UseSqlServerStorage(connectionString));\n// Then inject and use:\npublic class MyService(IBackgroundJobClient client)\n{\n    public void Run() => client.Enqueue(() => Console.WriteLine(\"hi\"));\n}","handlingStrategy":"validation","validationCode":"// Ensure storage is registered before any Hangfire API call\nif (JobStorage.Current == null) // This itself would throw, so check the static field state\n{\n    // Instead, initialize storage explicitly:\n    GlobalConfiguration.Configuration.UseSqlServerStorage(connectionString);\n}\n// Better: verify during startup that storage registration succeeded","typeGuard":null,"tryCatchPattern":"try\n{\n    var storage = JobStorage.Current;\n}\ncatch (InvalidOperationException)\n{\n    // Initialize storage or fail fast with a clear message\n    throw new InvalidOperationException(\"Hangfire storage not configured. Add services.AddHangfire(...) in Startup.\");\n}","preventionTips":["Register storage in the very first line of ConfigureServices / application start","Use DI-injected IBackgroundJobClient and IRecurringJobManager instead of static APIs in .NET Core","Add a startup health check that verifies JobStorage.Current is accessible","Log all exceptions during storage registration to catch silent failures"],"tags":["configuration","startup","job-storage","invalid-operation","di","hangfire"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}