{"record":{"id":"6308f7fff5334a2b","repo":"HangfireIO/Hangfire","slug":"storage","errorCode":null,"errorMessage":"storage","messagePattern":"storage","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"critical","filePath":"src/Hangfire.Core/BackgroundJobServer.cs","lineNumber":100,"sourceCode":"#pragma warning disable 618\n            : this(options, storage, additionalProcesses, null, null, null, null, null)\n#pragma warning restore 618\n        {\n        }\n\n        [Obsolete(\"Create your own BackgroundJobServer-like type and pass custom services to it. This constructor will be removed in 2.0.0.\")]\n        [EditorBrowsable(EditorBrowsableState.Advanced)]\n        public BackgroundJobServer(\n            [NotNull] BackgroundJobServerOptions options,\n            [NotNull] JobStorage storage,\n            [NotNull] IEnumerable<IBackgroundProcess> additionalProcesses,\n            [CanBeNull] IJobFilterProvider filterProvider,\n            [CanBeNull] JobActivator activator,\n            [CanBeNull] IBackgroundJobFactory factory,\n            [CanBeNull] IBackgroundJobPerformer performer,\n            [CanBeNull] IBackgroundJobStateChanger stateChanger)\n        {\n            if (storage == null) throw new ArgumentNullException(nameof(storage));\n            if (options == null) throw new ArgumentNullException(nameof(options));\n            if (additionalProcesses == null) throw new ArgumentNullException(nameof(additionalProcesses));\n\n            _options = options;\n\n            var processes = new List<IBackgroundProcessDispatcherBuilder>();\n            processes.AddRange(GetRequiredProcesses(filterProvider, activator, factory, performer, stateChanger));\n            processes.AddRange(additionalProcesses.Select(static x => x.UseBackgroundPool(1)));\n\n            var properties = new Dictionary<string, object>\n            {\n                { \"Queues\", options.Queues },\n                { \"WorkerCount\", options.WorkerCount }\n            };\n\n            _logger.Info($\"Starting Hangfire Server using job storage: '{storage}'\");\n\n            storage.WriteOptionsToLog(_logger);","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.Core/BackgroundJobServer.cs#L82-L118","documentation":"This ArgumentNullException(\"storage\") is thrown by the most detailed BackgroundJobServer constructor (the [Obsolete] one taking options, storage, additionalProcesses, filterProvider, activator, factory, performer, stateChanger) when the supplied JobStorage is null. The simpler constructors forward to JobStorage.Current when storage is omitted, so reaching this throw means either the advanced constructor was called explicitly with a null storage, or JobStorage.Current was null and was forwarded in.","triggerScenarios":"Calling `new BackgroundJobServer(options)` or `new BackgroundJobServer(options, storage)` while JobStorage.Current has never been set and storage is null; or calling the advanced constructor explicitly with a null storage argument.","commonSituations":"Startup ordering bug: BackgroundJobServer is constructed before GlobalConfiguration.Configuration.UseXXXStorage(...) runs; ASP.NET Core app that creates the server manually instead of via AddHangfireServer and never sets JobStorage.Current; environment-specific storage config (connection string) missing in a deployment; tests that spin up a server without configuring a storage (e.g. MemoryStorage).","solutions":["Call GlobalConfiguration.Configuration.UseMemoryStorage() (or a real storage) before constructing BackgroundJobServer.","Pass a non-null JobStorage explicitly to the constructor.","In ASP.NET Core, use services.AddHangfire(cfg => cfg.UseXxxStorage(...)) and AddHangfireServer() so storage is wired by the integration.","Verify the connection string / storage config is present in the target environment."],"exampleFix":"// before\nvar server = new BackgroundJobServer(); // JobStorage.Current is null\n\n// after\nGlobalConfiguration.Configuration.UseSqlServerStorage(\"HangfireDb\");\nvar server = new BackgroundJobServer();","handlingStrategy":"validation","validationCode":"if (JobStorage.Current is null)\n    throw new InvalidOperationException(\"JobStorage is not configured; call GlobalConfiguration.Configuration.UseXxxStorage first.\");\nvar server = new BackgroundJobServer();","typeGuard":"static bool IsStorageConfigured() => JobStorage.Current is not null;","tryCatchPattern":"try { var server = new BackgroundJobServer(options, storage); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"storage\") { throw new InvalidOperationException(\"Hangfire storage not configured at startup.\", ex); }","preventionTips":["Configure storage before constructing the server.","Use AddHangfire/AddHangfireServer in ASP.NET Core.","Verify the connection string per environment.","Add a startup health check for JobStorage.Current."],"tags":["csharp","hangfire","argumentnullexception","configuration","storage","startup","background-jobs"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}