HangfireIO/Hangfire · error · NotSupportedException

Misfire option '{0}' is not supported.

Error message

Misfire option '{0}' is not supported.

What it means

Thrown when a recurring job's stored 'Misfire' field parses to an integer that is not a defined MisfireHandlingMode value (0=Relaxed, 1=Strict, 2=Ignorable). This indicates corrupt or out-of-range data in the job storage's recurring-job hash/set, since well-formed clients only write valid enum integers.

Source

Thrown at src/Hangfire.Core/RecurringJobEntity.cs:89

                LastExecution = JobHelper.DeserializeDateTime(lastExecution);
            }

            if (recurringJob.TryGetValue("NextExecution", out var nextExecution) && !String.IsNullOrWhiteSpace(nextExecution))
            {
                NextExecution = JobHelper.DeserializeDateTime(nextExecution);
            }

            if (recurringJob.TryGetValue("CreatedAt", out var createdAt) && !String.IsNullOrWhiteSpace(createdAt))
            {
                CreatedAt = JobHelper.DeserializeDateTime(createdAt);
            }

            if (recurringJob.TryGetValue("Misfire", out var misfireStr))
            {
                MisfireHandling = (MisfireHandlingMode)Enum.Parse(typeof(MisfireHandlingMode), misfireStr);
                if (!Enum.IsDefined(typeof(MisfireHandlingMode), MisfireHandling))
                {
                    throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, "Misfire option '{0}' is not supported.", (int)MisfireHandling));
                }
            }
            else
            {
                MisfireHandling = MisfireHandlingMode.Relaxed;
            }

            if (recurringJob.TryGetValue("V", out var version) && !String.IsNullOrWhiteSpace(version))
            {
                Version = int.Parse(version, CultureInfo.InvariantCulture);
            }

            if (recurringJob.TryGetValue("RetryAttempt", out var attemptString) &&
                int.TryParse(attemptString, out var retryAttempt))
            {
                RetryAttempt = retryAttempt;
            }

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Correct or remove the 'Misfire' field for the offending recurring job in storage so it is absent (defaults to Relaxed) or a valid 0/1/2.
  2. Delete and recreate the recurring job via RecurringJob.AddOrUpdate to overwrite the corrupt entry.
  3. If using a custom storage, ensure it persists Misfire as the integer .ToString('D') of a valid MisfireHandlingMode.

Example fix

// before — storage contains: HSET recurring-job:myjob Misfire 5

// after — remove the corrupt field, let Hangfire recreate it:
// HDEL recurring-job:myjob Misfire
RecurringJob.AddOrUpdate("myjob", () => Work(), Cron.Daily());
Defensive patterns

Strategy: try-catch

Validate before calling

// Before reading, check the stored Misfire is a valid enum integer
var raw = connection.GetJobParameter(jobId, "Misfire");
if (raw != null && !int.TryParse(raw, out var m) || (m < 0 || m > 2))
{
    // log and reset
}

Try / catch

try { var job = connection.GetOrCreateRecurringJob(id); }
catch (NotSupportedException ex) when (ex.Message.Contains("Misfire")) { /* repair the entry */ }

Prevention

When it happens

Trigger: A recurring job entry in storage contains a 'Misfire' key with a value like '3' or '-1' or a non-integer, and RecurringJobEntity constructor parses it via Enum.Parse then Enum.IsDefined fails. Triggered when the scheduler or manager reads that job from storage.

Common situations: Manual edits to the Hangfire storage (SQL rows, Redis keys) that set an invalid Misfire value. A custom storage implementation writing the wrong value. Downgrading Hangfire after a future version introduced new misfire modes that an older version doesn't recognize.

Related errors


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