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

  1. Move the [Authorize] attribute (with RequireOutgoing) to the Hub class, not individual methods.
  2. If per-method auth is needed, use [Authorize] without RequireOutgoing on the method.
  3. 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

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


AI-assisted analysis of SignalR/SignalR@693053b89a (2026-08-13). Data as JSON: /api/errors/1ac29975c328ea13. Report an issue: GitHub.