SignalR/SignalR · error · ArgumentException
Outgoing authorization can only be required for an entire Hu
Error message
Outgoing authorization can only be required for an entire Hub, not a specific method.
What it means
Thrown by AuthorizeAttribute.AuthorizeHubMethodInvocation when the attribute has RequireOutgoing set to true and is applied to a method (appliesToMethod == true). SignalR's design cannot enforce outgoing authorization at the method level, so this is a runtime error flagging obviously incorrect attribute usage rather than silently allowing it.
Source
Thrown at src/Microsoft.AspNet.SignalR.Core/AuthorizeAttribute.cs:110
/// </summary>
/// <param name="hubIncomingInvokerContext">An <see cref="IHubIncomingInvokerContext"/> providing details regarding the <see cref="IHub"/> method invocation.</param>
/// <param name="appliesToMethod">Indicates whether the interface instance is an attribute applied directly to a method.</param>
/// <returns>true if the caller is authorized to invoke the <see cref="IHub"/> method; otherwise, false.</returns>
public virtual bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
if (hubIncomingInvokerContext == null)
{
throw new ArgumentNullException("hubIncomingInvokerContext");
}
// It is impossible to require outgoing auth at the method level with SignalR's current design.
// Even though this isn't the stage at which outgoing auth would be applied, we want to throw a runtime error
// to indicate when the attribute is being used with obviously incorrect expectations.
// We must explicitly check if _requireOutgoing is true since it is a Nullable type.
if (appliesToMethod && (_requireOutgoing == true))
{
throw new ArgumentException(Resources.Error_MethodLevelOutgoingAuthorization);
}
return UserAuthorized(hubIncomingInvokerContext.Hub.Context.User);
}
/// <summary>
/// When overridden, provides an entry point for custom authorization checks.
/// Called by <see cref="AuthorizeAttribute.AuthorizeHubConnection"/> and <see cref="AuthorizeAttribute.AuthorizeHubMethodInvocation"/>.
/// </summary>
/// <param name="user">The <see cref="System.Security.Principal.IPrincipal"/> for the client being authorize</param>
/// <returns>true if the user is authorized, otherwise, false</returns>
protected virtual bool UserAuthorized(IPrincipal user)
{
if (user == null)
{
return false;
}
View on GitHub (pinned to 693053b89a)
Solutions
- Move the [Authorize] attribute (with RequireOutgoing) to the Hub class, not individual methods.
- If per-method auth is needed, use [Authorize] without RequireOutgoing on the method.
- Review the XML doc on RequireOutgoing: it is a class-level-only parameter.
Example fix
// before (incorrect)
public class ChatHub : Hub
{
[Authorize(RequireOutgoing = true)]
public void Send(string msg) { }
}
// after (correct)
[Authorize(RequireOutgoing = true)]
public class ChatHub : Hub
{
public void Send(string msg) { }
} Defensive patterns
Strategy: validation
Validate before calling
// Apply [Authorize] with RequireOutgoing only at the class level
[AttributeUsage(AttributeTargets.Class)] // if you wrap AuthorizeAttribute
public class OutgoingAuthAttribute : AuthorizeAttribute { } Type guard
// In a startup validation pass, scan hub methods for Authorite attributes with outgoing required
foreach (var m in hubType.GetMethods())
{
var attr = m.GetCustomAttribute<AuthorizeAttribute>();
if (attr != null) { /* warn: ensure RequireOutgoing not set on method */ }
} Try / catch
try { base.AuthorizeHubMethodInvocation(ctx, appliesToMethod: true); }
catch (ArgumentException ex) when (ex.Message.Contains("Outgoing authorization"))
{
// misplaced attribute; log and fix placement
} Prevention
- Apply RequireOutgoing=true only at the Hub class level.
- Add a code-review checklist item for attribute placement on hubs.
- Write a startup test that scans hub methods for misconfigured [Authorize].
When it happens
Trigger: Placing [Authorize(Roles=..., RequireOutgoing=true)] (or an [Authorize] that defaults outgoing on) on an individual hub method instead of the hub class.
Common situations: Developer copies a class-level [Authorize] attribute onto a method expecting per-method outgoing auth; misunderstanding that RequireOutgoing is a hub-wide concern.
Related errors
- request
- hubIncomingInvokerContext
- Argument cannot be null or empty
- Unknown template type: + template
- JSON.stringify
AI-assisted analysis of SignalR/SignalR@693053b89a (2026-08-13).
Data as JSON: /api/errors/1ac29975c328ea13.
Report an issue: GitHub.