HangfireIO/Hangfire · error · ArgumentException

CRON expression is invalid. Please see the inner exception f

Error message

CRON expression is invalid. Please see the inner exception for details.

What it means

Thrown by RecurringJobManager.ValidateCronExpression as an ArgumentException wrapping any exception (CronFormatException, parse errors) from RecurringJobEntity.ParseCronExpression. It is the user-facing error for an unparseable cron string supplied to AddOrUpdate, preserving the original cause as InnerException.

Source

Thrown at src/Hangfire.Core/RecurringJobManager.cs:162

                {
                    using (var transaction = connection.CreateWriteTransaction())
                    {
                        transaction.UpdateRecurringJob(recurringJob, changedFields, _logger);
                        transaction.Commit();
                    }
                }
            }
        }
 
        private static void ValidateCronExpression(string cronExpression)
        {
            try
            {
                RecurringJobEntity.ParseCronExpression(cronExpression);
            }
            catch (Exception ex) when (ex.IsCatchableExceptionType())
            {
                throw new ArgumentException(
                    "CRON expression is invalid. Please see the inner exception for details.",
                    nameof(cronExpression),
                    ex);
            }
        }

        public void Trigger(string recurringJobId) => TriggerJob(recurringJobId);

        [Obsolete("Please use the `TriggerJob` method instead. Will be removed in 2.0.0.")]
        public string TriggerExecution(string recurringJobId) => TriggerJob(recurringJobId);

        public string TriggerJob(string recurringJobId)
        {
            if (recurringJobId == null) throw new ArgumentNullException(nameof(recurringJobId));

            using (var connection = _storage.GetConnection())
            using (connection.AcquireDistributedRecurringJobLock(recurringJobId, DefaultTimeout))
            {

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Inspect InnerException for the precise parse failure (often a CronFormatException with the offending field).
  2. Correct the cron string to a valid 5- or 6-field expression or a supported @macro.
  3. Validate cron at config-load time using RecurringJobEntity.ParseCronExpression or a cron library so startup fails fast with a clear message.

Example fix

// before
RecurringJob.AddOrUpdate("j", () => Work(), "0 25 * * *"); // hour out of range

// after
RecurringJob.AddOrUpdate("j", () => Work(), "0 23 * * *");
Defensive patterns

Strategy: validation

Validate before calling

static void ValidateCron(string cron)
{
    try { Hangfire.RecurringJobEntity.ParseCronExpression(cron); }
    catch (Exception ex) when (ex.IsCatchableExceptionType())
    { throw new ArgumentException($"Invalid cron: {cron}", ex); }
}

Try / catch

try { RecurringJob.AddOrUpdate(id, () => Work(), cron); }
catch (ArgumentException ex) when (ex.ParamName == "cronExpression")
{ /* inspect ex.InnerException for details */ }

Prevention

When it happens

Trigger: Calling recurringJobManager.AddOrUpdate(id, job, cronExpression, options) or RecurringJob.AddOrUpdate(id, methodCall, badCron, ...) where badCron fails parsing (wrong field count, invalid ranges, bad macro).

Common situations: Typo in a cron literal, using a 6-or-7-field expression on a path expecting 5, invalid characters, or a macro the Cronos parser rejects. Config-supplied cron that is malformed.

Related errors


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