HangfireIO/Hangfire · error · InvalidOperationException

JobActivator returned NULL instance of the

Error message

JobActivator returned NULL instance of the '{Type}' type.

What it means

Thrown as InvalidOperationException (wrapped in JobPerformanceException) when a JobActivator.ActivateJob returns null for the job's Type. Hangfire requires a non-null instance to invoke the method; a null return usually signals a misconfigured DI scope (e.g. a service not registered, a scoped service resolved outside its scope, or a manual activator returning null). The obsolete Activate() private method checks the result at line 84.

Solutions

  1. Register the job type in your DI container so the activator can resolve it (e.g. services.AddTransient<MyJob>()).
  2. Verify the job class has a public parameterless constructor if using the default JobActivator (Activator.CreateInstance), or register it for DI.
  3. If using a custom JobActivator, make ActivateJob throw a descriptive exception instead of returning null.
  4. Ensure the job type still exists in the deployed assembly — stale jobs referencing removed types should be deleted from storage.

Example fix

// before — MyJob not registered, DI activator returns null
// job fails: JobActivator returned NULL instance of the 'MyJob' type.

// after
services.AddTransient<MyJob>();
services.AddHangfire((sp, cfg) => cfg.UseActivator(new AspNetCoreJobActivator(sp)));
Defensive patterns

Strategy: try-catch

Validate before calling

// Before perform, verify the type is resolvable by your activator:
// (DI containers expose IsRegistered / TryResolve)
if (!serviceProvider.GetService(typeof(MyJob)).TryGetTarget(out _))
    throw new InvalidOperationException("Job type not registered.");

Try / catch

try { job.Perform(activator, token); }
catch (JobPerformanceException ex) when (ex.InnerException is InvalidOperationException ioe
    && ioe.Message.Contains("returned NULL"))
{
    logger.LogError(ex, "Job type could not be activated — register it in DI.");
}

Prevention

When it happens

Trigger: Job.Perform (obsolete) invokes Activate(activator) -> activator.ActivateJob(Type) which returns null. Common with a custom JobActivator whose Resolve/ActivateJob returns null, or a DI-based activator (AspNetCoreJobActivator, Autofac) that cannot resolve the job type because it isn't registered in the container.

Common situations: The job class is not registered in the DI container (especially with scoped/lifetime resolution in ASP.NET Core); a constructor on the job type throws silently or the DI provider returns null for an unregistered service; using a third-party activator that returns null for open generics or interface-based jobs; a stale job in storage referencing a type that was since removed from the assembly.

Related errors


AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13). Data as JSON: /api/errors/e98469fd774f95fd. Report an issue: GitHub.

Appendix: source

Thrown at src/Hangfire.Core/Obsolete/Job.Obsolete.cs:84

            }
            finally
            {
                Dispose(instance);
            }

            return result;
        }

        [Obsolete("Will be removed in 2.0.0")]
        private object Activate(JobActivator activator)
        {
            try
            {
                var instance = activator.ActivateJob(Type);

                if (instance == null)
                {
                    throw new InvalidOperationException($"JobActivator returned NULL instance of the '{Type}' type.");
                }

                return instance;
            }
            catch (Exception ex) when (ex.IsCatchableExceptionType())
            {
                throw new JobPerformanceException(
                    "An exception occurred during job activation.",
                    ex);
            }
        }

        [Obsolete("Will be removed in 2.0.0")]
        private object[] GetArguments(IJobCancellationToken cancellationToken)
        {
            try
            {
                var parameters = Method.GetParameters();

View on GitHub (pinned to c236dd0f93)