HangfireIO/Hangfire · warning · NotSupportedException

Server '{context.ServerId}' can't process recurring job '{re

Error message

Server '{context.ServerId}' can't process recurring job '{recurringJobId}' of version '{recurringJob.Version ?? 1}'. Max supported version of this server is '{MaxSupportedVersion}'.

What it means

Thrown by RecurringJobScheduler.ScheduleRecurringJob when a recurring job's stored Version is greater than MaxSupportedVersion (currently 2). Newer Hangfire servers may write higher-version recurring jobs with features older servers don't understand; rather than misprocess them, the older server refuses and reschedules. The job is retried with a warning rather than disabling the whole scheduler.

Source

Thrown at src/Hangfire.Core/Server/RecurringJobScheduler.cs:319

            string recurringJobId, RecurringJobEntity recurringJob, DateTime now)
        {
            // We always start a transaction, regardless our recurring job was updated or not,
            // to prevent from infinite loop, when there's an old processing server (pre-1.7.0)
            // in our environment that doesn't know it should modify the score for entries in
            // the recurring jobs set.
            using (var transaction = connection.CreateWriteTransaction())
            {
                Exception exception = null;
                
                try
                {
                    // We can't handle recurring job with unsupported versions - there may be additional
                    // features. we don't know about. We also shouldn't stop the whole scheduler as
                    // there may be jobs with lower versions. Instead, we'll re-schedule such a job and
                    // emit a warning message to the log.
                    if (recurringJob.Version.HasValue && recurringJob.Version > MaxSupportedVersion)
                    {
                        throw new NotSupportedException($"Server '{context.ServerId}' can't process recurring job '{recurringJobId}' of version '{recurringJob.Version ?? 1}'. Max supported version of this server is '{MaxSupportedVersion}'.");
                    }
                    
                    var backgroundJobs = new List<BackgroundJob>();
                    var precision = _pollingDelay + _pollingDelay;

                    var executions = recurringJob.ScheduleNext(
                        _timeZoneResolver,
                        recurringJob.LastExecution ?? recurringJob.CreatedAt?.AddSeconds(-1) ?? now.AddSeconds(-1),
                        now,
                        precision);

                    foreach (var execution in executions)
                    {
                        var backgroundJob = _factory.TriggerRecurringJob(
                            context.Storage,
                            connection,
                            _profiler,
                            recurringJob,

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Upgrade all processing servers to a version that supports the recurring job's Version (>= the version that wrote it).
  2. Recreate the recurring job with a client whose version matches the servers (to reset Version to a supported value).
  3. During rolling upgrades, drain old servers before new servers write higher-version jobs.

Example fix

// before — mixed versions: v1.8 server reads job written by v1.9+
// (Version=3 > MaxSupportedVersion=2)

// after — upgrade all servers to the same (latest) version
dotnet add package Hangfire.Core --version 1.9.0
Defensive patterns

Strategy: validation

Validate before calling

// Ensure all servers are on a version that supports the recurring job schema version
var asm = typeof(RecurringJob).Assembly.GetName().Version;
if (asm < new Version(1, 7, 0)) throw new InvalidOperationException("Upgrade servers to match schema version.");

Try / catch

// The scheduler already catches this per-job and retries/disables; monitor the warning log
// for 'can't process recurring job' and upgrade servers.

Prevention

When it happens

Trigger: A mixed-version Hangfire deployment: a newer server creates a v>2 recurring job, then an older server (MaxSupportedVersion=2) picks it up during its polling cycle and throws this inside the per-job try block.

Common situations: Rolling upgrade where new and old servers coexist temporarily. A test/staging environment created by a newer version being read by an older one. Pointing an older client/server at storage written by a newer version.

Related errors


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