HangfireIO/Hangfire · critical · InvalidOperationException
No dispatchers registered for the processing server.
Error message
No dispatchers registered for the processing server.
What it means
Thrown by BackgroundServerProcess.StartDispatchers when the server was constructed with an empty dispatcher-builders array. A processing server requires at least one dispatcher (e.g. a worker) to actually execute jobs; with none, the server would idle forever, so Hangfire treats it as a configuration error.
Source
Thrown at src/Hangfire.Core/Server/BackgroundServerProcess.cs:247
connection.RemoveServer(context.ServerId);
}
stopwatch.Stop();
_logger.Info($"{GetServerTemplate(context.ServerId)} successfully reported itself as stopped in {stopwatch.Elapsed.TotalMilliseconds} ms");
_logger.Info($"{GetServerTemplate(context.ServerId)} has been stopped in total {stoppedAt?.Elapsed.TotalMilliseconds ?? 0} ms");
}
catch (Exception ex) when (ex.IsCatchableExceptionType())
{
_logger.WarnException($"{GetServerTemplate(context.ServerId)} there was an exception, server may not be removed", ex);
}
}
private void StartDispatchers(BackgroundServerContext context, ICollection<IBackgroundDispatcher> dispatchers)
{
if (_dispatcherBuilders.Length == 0)
{
throw new InvalidOperationException("No dispatchers registered for the processing server.");
}
_logger.Info($"{GetServerTemplate(context.ServerId)} is starting the registered dispatchers: {String.Join(", ", _dispatcherBuilders.Select(static builder => $"{builder}"))}...");
foreach (var dispatcherBuilder in _dispatcherBuilders)
{
dispatchers.Add(dispatcherBuilder.Create(context, _options));
}
_logger.Info($"{GetServerTemplate(context.ServerId)} all the dispatchers started");
}
private void WaitForDispatchers(
BackgroundServerContext context,
IReadOnlyList<IBackgroundDispatcher> dispatchers)
{
if (dispatchers.Count == 0) return;
View on GitHub (pinned to c236dd0f93)
Solutions
- Ensure at least one worker/dispatcher is registered — the default BackgroundJobServer adds Worker dispatchers automatically.
- When using a custom server composition, include at least one IBackgroundProcessDispatcherBuilder in the builders list.
- Verify the options/processes collection passed to the server constructor is non-empty.
Example fix
// before
var server = new BackgroundJobServer(new BackgroundJobServerOptions { WorkerCount = 0 });
server.Start(); // throws
// after
var server = new BackgroundJobServer(); // WorkerCount defaults to a positive value
server.Start(); Defensive patterns
Strategy: validation
Validate before calling
var options = new BackgroundJobServerOptions { WorkerCount = Environment.ProcessorCount };
if (options.WorkerCount <= 0) options.WorkerCount = 1;
var server = new BackgroundJobServer(options); Prevention
- Use the default BackgroundJobServer constructor which registers workers automatically.
- Never set WorkerCount to 0 for a processing server.
- When composing a custom server, include at least one dispatcher builder.
When it happens
Trigger: Constructing a BackgroundJobServer (or the underlying BackgroundServerProcess) with no dispatcher builders — e.g. an empty processes/dispatchers list, or a custom server assembly that filters out all builders.
Common situations: Misconfigured BackgroundJobServerOptions or a custom IBackgroundProcess that yields no dispatchers. Using the minimal server API with an empty process array. A DI registration that mistakenly provides an empty collection.
Related errors
- Current JobStorage instance has not been initialized yet. Yo
- ServerTimeout must be either non-negative and equal to or le
- CheckInterval must be either non-negative and equal to or le
- Can't perform a background job with a null job.
- Could not get a value of the job parameter `{name}`. See inn
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/73735f4b07099a22.
Report an issue: GitHub.