HangfireIO/Hangfire · error · NotSupportedException
Only public methods can be invoked in the background. Ensure
Error message
Only public methods can be invoked in the background. Ensure your method has the `public` access modifier, and you aren't using explicit interface implementation.
What it means
NotSupportedException thrown by Job.Validate when the target method is not public. Hangfire invokes job methods by reflection in a separate (possibly different) process, so non-public methods (private, protected, internal) and explicit interface implementations are rejected at job-definition time because they cannot be reliably invoked across process boundaries and serialized metadata. The error message explicitly calls out explicit interface implementation as a common culprit (the generated method is private).
Source
Thrown at src/Hangfire.Core/Common/Job.cs:477
type,
method,
GetExpressionValues(callExpression.Arguments),
queue);
}
private static void Validate(
Type type,
[InvokerParameterName] string typeParameterName,
MethodInfo method,
// ReSharper disable once UnusedParameter.Local
[InvokerParameterName] string methodParameterName,
// ReSharper disable once UnusedParameter.Local
int argumentCount,
[InvokerParameterName] string argumentParameterName)
{
if (!method.IsPublic)
{
throw new NotSupportedException("Only public methods can be invoked in the background. Ensure your method has the `public` access modifier, and you aren't using explicit interface implementation.");
}
if (method.ContainsGenericParameters)
{
throw new NotSupportedException("Job method can not contain unassigned generic type parameters.");
}
if (method.DeclaringType == null)
{
throw new NotSupportedException("Global methods are not supported. Use class methods instead.");
}
if (!method.DeclaringType.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))
{
throw new ArgumentException(
$"The type `{method.DeclaringType}` must be derived from the `{type}` type.",
typeParameterName);
}View on GitHub (pinned to c236dd0f93)
Solutions
- Change the method's access modifier to public.
- If the method is an explicit interface implementation, enqueue against the interface using BackgroundJob.Enqueue<IFoo>(x => x.Bar()).
- Move the job method to a public service class if the current type cannot be made public.
Example fix
// before — private / explicit interface impl
public class Worker {
void IJob.Run() { ... } // explicit impl → private backing method
private void DoRun() { ... }
}
BackgroundJob.Enqueue<Worker>(x => ((IJob)x).Run());
// after — public method, or enqueue against the interface
public class Worker : IJob {
public void Run() { ... } // public
}
BackgroundJob.Enqueue<IJob>(x => x.Run()); Defensive patterns
Strategy: validation
Validate before calling
if (!method.IsPublic)
throw new NotSupportedException($"Method {method.Name} must be public to be used as a job method.");
// or check at design time: ensure the job method has the 'public' modifier. Type guard
public static bool IsPublicJobMethod(MethodInfo m) => m != null && m.IsPublic;
Try / catch
try { BackgroundJob.Enqueue<T>(x => x.Work()); }
catch (NotSupportedException ex) when (ex.Message.Contains("public methods")) { /* make the method public or enqueue the interface */ } Prevention
- Keep job methods public.
- For explicit interface implementations, enqueue against the interface type: Enqueue<IFoo>(x => x.Bar()).
- Add a unit test that reflects over job methods and asserts IsPublic to catch regressions.
When it happens
Trigger: Enqueuing () => obj.PrivateMethod(); a method marked internal, protected, or private; a method that is an explicit interface implementation (void IFoo.Bar()) whose backing method is private; a method on an internal type.
Common situations: Refactoring a public method to private; using explicit interface implementation and enqueuing the concrete type; enqueuing a method defined on an internal class; F# or VB code where default accessibility differs from C#.
Related errors
- Job method can not contain unassigned generic type parameter
- Global methods are not supported. Use class methods instead.
- The type `{method.DeclaringType}` must be derived from the `
- Async void methods are not supported. Use async Task instead
- Argument count must be equal to method parameter count.
AI-assisted analysis of HangfireIO/Hangfire@c236dd0f93 (2026-08-13).
Data as JSON: /api/errors/6527f1a09509e4c5.
Report an issue: GitHub.