HangfireIO/Hangfire · error · JobPerformanceException
An exception occurred during performance of the job.
Error message
An exception occurred during performance of the job.
What it means
Thrown by CoreBackgroundJobPerformer.HandleJobPerformanceException as a JobPerformanceException wrapping any non-cancellation, non-abort exception raised while executing the job method. Hangfire wraps user exceptions to preserve a shallow stack trace and to mark the job failed. The original exception is the InnerException.
Source
Thrown at src/Hangfire.Core/Server/CoreBackgroundJobPerformer.cs:105
{
// OperationCanceledException exception is thrown because
// ServerJobCancellationWatcher has detected the job was aborted.
throw new JobAbortedException();
}
if (exception is OperationCanceledException && cancellationToken.ShutdownToken.IsCancellationRequested)
{
// OperationCanceledException exceptions are treated differently from
// others, when ShutdownToken's cancellation was requested, to notify
// a worker that job performance was aborted by a shutdown request,
// and a job identifier should BE re-queued.
ExceptionDispatchInfo.Capture(exception).Throw();
throw exception;
}
// Other exceptions are wrapped with JobPerformanceException to preserve a
// shallow stack trace without Hangfire methods.
throw new JobPerformanceException(
"An exception occurred during performance of the job.",
exception, job?.Id);
}
private object InvokeMethod(PerformContext context, object instance, object[] arguments)
{
if (context.BackgroundJob.Job == null) return null;
try
{
var methodInfo = context.BackgroundJob.Job.Method;
var method = new BackgroundJobMethod(methodInfo, instance, arguments);
var returnType = methodInfo.ReturnType;
if (returnType.IsTaskLike(out var getTaskFunc))
{
if (_taskScheduler != null)
{View on GitHub (pinned to c236dd0f93)
Solutions
- Inspect InnerException of the JobPerformanceException to find the real cause and fix the job code.
- Add try/catch inside the job method to handle expected exceptions and avoid polluting the failed-jobs list.
- Configure AutomaticRetryAttribute to retry transient failures and FailedState thresholds appropriately.
Example fix
// before
public void Run()
{
var data = _repo.Get(id); // may throw
Process(data.Value);
}
// after
public void Run()
{
try
{
var data = _repo.Get(id);
Process(data.Value);
}
catch (NotFoundException ex)
{
_logger.Warn(ex, "item not found, skipping");
}
} Defensive patterns
Strategy: try-catch
Try / catch
// In the job method, handle expected exceptions
public void Run()
{
try { /* work */ }
catch (TransientException) { throw; } // let Hangfire retry
catch (BusinessException ex) { _logger.Warn(ex, "skipped"); }
} Prevention
- Inspect the InnerException of JobPerformanceException to find the real cause.
- Handle expected exceptions inside the job method to avoid failed-state churn.
- Use [AutomaticRetry] for transient failures and tune retry counts.
When it happens
Trigger: The job method (or an async Task it returns) throws any exception that is not a JobAbortedException or a relevant OperationCanceledException. The performer catches it and rethrows wrapped.
Common situations: The job method throws due to a bug, null reference, business-rule violation, network error, DB constraint, etc. Any unhandled exception in the job body surfaces this way.
Related errors
- Can't perform a background job with a null job.
- JobActivator returned NULL instance of the '{context.Backgro
- Could not get a value of the job parameter `{name}`. See inn
- An exception occurred during job activation.
- An exception occurred during arguments deserialization.
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/a3bae6a45fef9275.
Report an issue: GitHub.