microsoft/garnet · error · Exception
Unable to call ThreadPool.SetMaxThreads with {maxThreads}, {
Error message
Unable to call ThreadPool.SetMaxThreads with {maxThreads}, {maxCPThreads} What it means
Thrown by GarnetServer.InitializeServer when ThreadPool.SetMaxThreads returns false on the retry attempt. The code first tries to set max threads, then sets min threads, then retries max threads if the first attempt didn't succeed (because the CLR requires min <= max). If this final retry also fails, the server cannot proceed.
Source
Thrown at libs/host/GarnetServer.cs:241
maxThreads = opts.ThreadPoolMaxThreads;
maxChanged = true;
}
if (opts.ThreadPoolMaxIOCompletionThreads > 0)
{
maxCPThreads = opts.ThreadPoolMaxIOCompletionThreads;
maxChanged = true;
}
// First try to set the max threads
var setMax = !maxChanged || ThreadPool.SetMaxThreads(maxThreads, maxCPThreads);
// Set the min threads
if (minChanged && !ThreadPool.SetMinThreads(minThreads, minCPThreads))
throw new Exception($"Unable to call ThreadPool.SetMinThreads with {minThreads}, {minCPThreads}");
// Retry to set max threads if it wasn't set in the earlier step
if (!setMax && !ThreadPool.SetMaxThreads(maxThreads, maxCPThreads))
throw new Exception($"Unable to call ThreadPool.SetMaxThreads with {maxThreads}, {maxCPThreads}");
opts.Initialize(loggerFactory);
StoreWrapper.DatabaseCreatorDelegate createDatabaseDelegate = (int dbId) =>
CreateDatabase(dbId, opts, clusterFactory, customCommandManager);
if (!opts.DisablePubSub)
subscribeBroker = new SubscribeBroker(null, opts.PubSubPageSizeBytes(), pubSubEpoch, startFresh: true, logger);
logger?.LogTrace("TLS is {tlsEnabled}", opts.TlsOptions == null ? "disabled" : "enabled");
// Create Garnet TCP server if none was provided.
if (servers == null)
{
servers = new IGarnetServer[opts.EndPoints.Length];
for (var i = 0; i < servers.Length; i++)
{
if (opts.EndPoints[i] is UnixDomainSocketEndPoint)
{View on GitHub (pinned to 951b0fc683)
Solutions
- Ensure ThreadPoolMaxThreads >= ThreadPoolMinThreads and ThreadPoolMaxIOCompletionThreads >= ThreadPoolMinIOCompletionThreads.
- Increase max thread values or decrease min thread values so the constraint is satisfied.
- If running in containers, verify the host allows the requested thread counts.
- Consider not overriding thread pool settings and letting the runtime self-tune.
Example fix
// before
var opts = new GarnetServerOptions
{
ThreadPoolMinThreads = 200,
ThreadPoolMaxThreads = 100 // max < min is invalid
};
// after
var opts = new GarnetServerOptions
{
ThreadPoolMinThreads = 100,
ThreadPoolMaxThreads = 200
}; Defensive patterns
Strategy: validation
Validate before calling
if (opts.ThreadPoolMaxThreads > 0 || opts.ThreadPoolMaxIOCompletionThreads > 0)
{
ThreadPool.GetMinThreads(out var minWorker, out var minIO);
if (opts.ThreadPoolMaxThreads > 0 && opts.ThreadPoolMaxThreads < minWorker)
throw new InvalidOperationException($"Max worker threads ({opts.ThreadPoolMaxThreads}) is below min ({minWorker})");
if (opts.ThreadPoolMaxIOCompletionThreads > 0 && opts.ThreadPoolMaxIOCompletionThreads < minIO)
throw new InvalidOperationException($"Max IO threads ({opts.ThreadPoolMaxIOCompletionThreads}) is below min ({minIO})");
} Type guard
static bool AreMaxThreadSettingsValid(GarnetServerOptions opts)
{
ThreadPool.GetMinThreads(out var minWorker, out var minIO);
return (opts.ThreadPoolMaxThreads <= 0 || opts.ThreadPoolMaxThreads >= minWorker)
&& (opts.ThreadPoolMaxIOCompletionThreads <= 0 || opts.ThreadPoolMaxIOCompletionThreads >= minIO);
} Prevention
- Ensure max thread values are always >= min thread values.
- Set min and max thread values together as a consistent pair.
- Let the runtime self-tune the thread pool unless you have profiling data.
When it happens
Trigger: Setting ThreadPoolMaxThreads or ThreadPoolMaxIOCompletionThreads to values the CLR rejects — typically values below the current min thread counts, zero, or values exceeding system limits. The retry at line 240 fires when the first SetMaxThreads at line 233 also failed.
Common situations: Setting max threads lower than min threads in the same config; container CPU/memory constraints that limit max threads; OS-level thread pool caps; configuring max threads to values below the .NET runtime minimum.
Related errors
- Unable to call ThreadPool.SetMinThreads with {minThreads}, {
- Authentication mode {AuthenticationMode} is not supported.
- Encountered an error when initializing Garnet server. Please
- AofMemorySize (effective {effectiveMemory} after rounding do
- AofPageSize (effective {effectivePage} after rounding down t
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/da2b39ee0a45e46d.
Report an issue: GitHub.