HangfireIO/Hangfire · error · NotSupportedException

MonitoringApi should inherit the `JobStorageMonitor` class

Error message

MonitoringApi should inherit the `JobStorageMonitor` class

What it means

The Awaiting Jobs dashboard page (AwaitingJobsPage.cshtml:31) checks whether the storage's monitoring API supports the awaiting-jobs feature. If JobStorageFeatures.Monitoring.AwaitingJobs is advertised but the monitoring API does not inherit from JobStorageMonitor, a NotSupportedException is thrown because the page needs to call monitor.AwaitingCount() and monitor.AwaitingJobs() which are defined on JobStorageMonitor.

Source

Thrown at src/Hangfire.Core/Dashboard/Pages/AwaitingJobsPage.cshtml:31

@{
    Layout = new LayoutPage(Strings.AwaitingJobsPage_Title);

    int from, perPage;

    int.TryParse(Query("from"), out from);
    int.TryParse(Query("count"), out perPage);

    List<string> jobIds = null;
    Pager pager = null;
    JobList <AwaitingJobDto> jobs = null;
    int jobCount = 0;

    if (Storage.HasFeature(JobStorageFeatures.Monitoring.AwaitingJobs))
    {
        var monitor = Storage.GetMonitoringApi() as JobStorageMonitor;
        if (monitor == null) 
        {
            throw new NotSupportedException("MonitoringApi should inherit the `JobStorageMonitor` class");
        }

        pager = new Pager(from, perPage, DashboardOptions.DefaultRecordsPerPage, monitor.AwaitingCount());
        jobs = monitor.AwaitingJobs(pager.FromRecord, pager.RecordsPerPage);
        jobCount = jobs.Count;
    }
    else
    {
        using (var connection = Storage.GetReadOnlyConnection())
        {
            var storageConnection = connection as JobStorageConnection;

            if (storageConnection != null)
            {
                pager = new Pager(from, perPage, DashboardOptions.DefaultRecordsPerPage, storageConnection.GetSetCount("awaiting"));
                jobIds = storageConnection.GetRangeFromSet("awaiting", pager.FromRecord, pager.FromRecord + pager.RecordsPerPage - 1);
                jobCount = jobIds.Count;
            }

View on GitHub (pinned to c236dd0f93)

Solutions

  1. Make your custom MonitoringApi class inherit from JobStorageMonitor and implement AwaitingCount() and AwaitingJobs().
  2. Do not advertise JobStorageFeatures.Monitoring.AwaitingJobs in your storage's feature set if the monitoring API does not support it.
  3. Upgrade to a storage provider version that is compatible with the Hangfire.Core version in use.

Example fix

// before
public class MyMonitoringApi : IMonitoringApi
{
    // missing AwaitingCount / AwaitingJobs
}

// after
public class MyMonitoringApi : JobStorageMonitor
{
    public override int AwaitingCount() { /* query storage */ }
    public override JobList<AwaitingJobDto> AwaitingJobs(int from, int count) { /* query storage */ }
}
Defensive patterns

Strategy: type-guard

Validate before calling

var monitor = storage.GetMonitoringApi();
if (!(monitor is JobStorageMonitor))
    throw new InvalidOperationException(
        "Monitoring API must inherit JobStorageMonitor to use the Awaiting Jobs feature.");

Type guard

static bool SupportsAwaitingJobs(JobStorage storage)
{
    if (!storage.HasFeature(JobStorageFeatures.Monitoring.AwaitingJobs)) return false;
    return storage.GetMonitoringApi() is JobStorageMonitor;
}

Prevention

When it happens

Trigger: A custom JobStorage implementation declares the AwaitingJobs monitoring feature flag but its monitoring API class does not derive from JobStorageMonitor.

Common situations: Building a custom storage provider and incorrectly advertising the AwaitingJobs feature; upgrading Hangfire and the storage provider has not been updated to match the new feature surface.

Related errors


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