HangfireIO/Hangfire · error · InvalidOperationException
Unsupported filter instance
Error message
Unsupported filter instance
What it means
JobFilterCollection.ValidateFilterInstance (JobFilterCollection.cs:143) guards Add/AddRange calls: only objects implementing at least one Hangfire filter interface (IClientFilter, IServerFilter, IClientExceptionFilter, IServerExceptionFilter, IApplyStateFilter, IElectStateFilter) are accepted. Anything else is rejected because the filter pipeline cannot invoke lifecycle hooks on an incompatible object.
Source
Thrown at src/Hangfire.Core/Common/JobFilterCollection.cs:143
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
// ReSharper disable once UnusedParameter.Local
private static void ValidateFilterInstance(object instance)
{
if (instance != null &&
!(instance is IClientFilter
|| instance is IServerFilter
|| instance is IClientExceptionFilter
|| instance is IServerExceptionFilter
|| instance is IApplyStateFilter
|| instance is IElectStateFilter))
{
throw new InvalidOperationException("Unsupported filter instance");
}
}
}
}View on GitHub (pinned to c236dd0f93)
Solutions
- Make the class implement the appropriate Hangfire filter interface (IServerFilter for server-side OnPerforming/OnPerformed, IClientFilter for client-side, etc.).
- Verify the type implements one of: IClientFilter, IServerFilter, IClientExceptionFilter, IServerExceptionFilter, IApplyStateFilter, IElectStateFilter.
- If it is a third-party type, wrap it in an adapter class that implements the correct interface.
Example fix
// before
public class RequestLogger { public void Log() { ... } }
GlobalJobFilters.Filters.Add(new RequestLogger());
// after
public class RequestLogger : IServerFilter
{
public void OnPerforming(PerformingContext ctx) { /* log */ }
public void OnPerformed(PerformedContext ctx) { }
}
GlobalJobFilters.Filters.Add(new RequestLogger()); Defensive patterns
Strategy: type-guard
Validate before calling
static bool IsHangfireFilter(object instance) =>
instance is IClientFilter ||
instance is IServerFilter ||
instance is IClientExceptionFilter ||
instance is IServerExceptionFilter ||
instance is IApplyStateFilter ||
instance is IElectStateFilter;
if (!IsHangfireFilter(myInstance))
throw new InvalidOperationException($"{myInstance.GetType()} is not a Hangfire filter.");
GlobalJobFilters.Filters.Add(myInstance); Type guard
static bool IsHangfireFilter(object instance) =>
instance is IClientFilter ||
instance is IServerFilter ||
instance is IClientExceptionFilter ||
instance is IServerExceptionFilter ||
instance is IApplyStateFilter ||
instance is IElectStateFilter; Prevention
- Always implement the correct Hangfire filter interface on classes added to GlobalJobFilters.Filters.
- Do not add DI service instances or non-Hangfire attributes to the filter collection.
- Use a type check helper before registration when filters come from reflection/plugin loading.
When it happens
Trigger: Calling GlobalJobFilters.Filters.Add(someObject) or jobFilterCollection.Add(instance) where instance does not implement any of the six recognized filter interfaces.
Common situations: Registering a plain class, a logging middleware, or a third-party attribute that is not a Hangfire filter; accidentally adding a service instance meant for DI; adding an MVC/ASP.NET filter attribute instead of a Hangfire one.
Related errors
- The Order value should be greater or equal to '-1'
- Could not get a value of the job parameter `{name}`. See inn
- Could not get a value of the job parameter `{name}`. See inn
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/1a35d67fd4378cc1.
Report an issue: GitHub.