HangfireIO/Hangfire · critical · InvalidOperationException
Current JobStorage instance has not been initialized yet. Yo
Error message
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`.
What it means
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.
Source
Thrown at src/Hangfire.Core/JobStorage.cs:42
namespace Hangfire
{
public abstract class JobStorage
{
private static readonly object LockObject = new object();
private static JobStorage _current;
private TimeSpan _jobExpirationTimeout = TimeSpan.FromDays(1);
public static JobStorage Current
{
get
{
lock (LockObject)
{
if (_current == null)
{
throw new InvalidOperationException(
"Current JobStorage instance has not been initialized yet. You must set it before using Hangfire Client or Server API. " +
#if NET45 || NET46
"For NET Framework applications please use GlobalConfiguration.UseXXXStorage method, where XXX is the storage type, like `UseSqlServerStorage`."
#else
"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`."
#endif
);
}
return _current;
}
}
set
{
lock (LockObject)
{
_current = value;
}View on GitHub (pinned to c236dd0f93)
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)
Example fix
// before (.NET Core)
BackgroundJob.Enqueue(() => Console.WriteLine("hi"));
// throws: JobStorage.Current not initialized
// after
// In Startup.ConfigureServices:
services.AddHangfire(config =>
config.UseSqlServerStorage(connectionString));
// Then inject and use:
public class MyService(IBackgroundJobClient client)
{
public void Run() => client.Enqueue(() => Console.WriteLine("hi"));
} Defensive patterns
Strategy: validation
Validate before calling
// Ensure storage is registered before any Hangfire API call
if (JobStorage.Current == null) // This itself would throw, so check the static field state
{
// Instead, initialize storage explicitly:
GlobalConfiguration.Configuration.UseSqlServerStorage(connectionString);
}
// Better: verify during startup that storage registration succeeded Try / catch
try
{
var storage = JobStorage.Current;
}
catch (InvalidOperationException)
{
// Initialize storage or fail fast with a clear message
throw new InvalidOperationException("Hangfire storage not configured. Add services.AddHangfire(...) in Startup.");
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- storage
- JobStorage.JobExpirationTimeout value should be equal or gre
- Unable to find the required services. Please add all the req
- client
- options
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/6e4a3ab5e40e4518.
Report an issue: GitHub.