SignalR/SignalR · error · InvalidOperationException
The queue is full.
Error message
The queue is full.
What it means
Thrown by ScaleoutStream.Send when UsingTaskQueue is true and _queue.Enqueue returns null, meaning the task queue has reached its maximum capacity. This is backpressure: the scaleout stream's send queue (bounded by configuration.MaxQueueLength) is full because messages are arriving faster than the backplane can acknowledge them. The stream cannot buffer any more messages and rejects the send.
Source
Thrown at src/Microsoft.AspNet.SignalR.Core/Messaging/ScaleoutStream.cs:116
var context = new SendContext(this, send, state);
if (_initializeDrainTask != null && !_initializeDrainTask.IsCompleted)
{
// Wait on the draining of the queue before proceeding with the send
// NOTE: Calling .Wait() here is safe because the task wasn't created on an ASP.NET request thread
// and thus has no captured sync context
_initializeDrainTask.Wait();
}
if (UsingTaskQueue)
{
Task task = _queue.Enqueue(Send, context);
if (task == null)
{
// The task is null if the queue is full
throw new InvalidOperationException(Resources.Error_TaskQueueFull);
}
// Always observe the task in case the user doesn't handle it
return task.Catch(_trace);
}
return Send(context);
}
}
public void SetError(Exception error)
{
Trace(TraceEventType.Error, "Error has happened with the following exception: {0}.", error);
lock (_lockObj)
{
_perfCounters.ScaleoutErrorsTotal.Increment();
_perfCounters.ScaleoutErrorsPerSec.Increment();View on GitHub (pinned to 693053b89a)
Solutions
- Investigate backplane health — check Redis/SQL/Service Bus latency and capacity.
- Increase MaxQueueLength in ScaleoutConfiguration if the backplane can sustain higher catch-up load.
- Implement client-side throttling or message batching to reduce send rate.
- Consider a higher-throughput backplane (e.g., Redis over Service Bus).
Example fix
// before — default small queue
var config = new ScaleoutConfiguration() { MaxQueueLength = 50 };
// after — larger queue to absorb bursts
var config = new ScaleoutConfiguration() { MaxQueueLength = 1000 }; Defensive patterns
Strategy: retry
Try / catch
try {
streamManager.Send(streamIndex, messages);
} catch (InvalidOperationException ex) when (ex.Message.Contains("queue is full")) {
// Backpressure — back off and retry, or drop/throttle
logger.Warn("Scaleout queue full, applying backpressure", ex);
await Task.Delay(backoffDelay);
// consider reducing send rate or increasing MaxQueueLength
} Prevention
- Size MaxQueueLength appropriately for peak message throughput.
- Monitor scaleout queue length performance counter.
- Ensure the backplane has sufficient capacity (Redis cluster, SQL tier, etc.).
- Implement client-side throttling to prevent overwhelming the backplane.
When it happens
Trigger: The scaleout backplane is slow or unresponsive, causing the send queue to fill up to MaxQueueLength. Each call to Send attempts _queue.Enqueue; when the queue is at capacity it returns null and the exception fires. Common during backplane outages or severe network latency.
Common situations: Redis/SQL/Service Bus backplane is down or slow; sudden message burst exceeding backplane throughput; MaxQueueLength configured too small for the load; network partition between app servers and backplane; the backplane connection is in a buffering state for too long.
Related errors
- The stream has been closed.
- Scaleout queuing is enabled but maximum queue size is 0
- SignalR: Error loading hubs. Ensure your hubs reference is c
- SignalR: Invalid transport(s) specified, aborting start.
- Query string property must be either a string or object.
AI-assisted analysis of SignalR/SignalR@693053b89a (2026-08-13).
Data as JSON: /api/errors/9c520e08e845e45e.
Report an issue: GitHub.