{"record":{"id":"7bf7893eca9a8333","repo":"microsoft/garnet","slug":"unable-to-call-threadpool-setminthreads-with-mint","errorCode":null,"errorMessage":"Unable to call ThreadPool.SetMinThreads with {minThreads}, {minCPThreads}","messagePattern":"Unable to call ThreadPool\\.SetMinThreads with (.+?), (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"libs/host/GarnetServer.cs","lineNumber":237,"sourceCode":"                minChanged = true;\n            }\n            if (opts.ThreadPoolMaxThreads > 0)\n            {\n                maxThreads = opts.ThreadPoolMaxThreads;\n                maxChanged = true;\n            }\n            if (opts.ThreadPoolMaxIOCompletionThreads > 0)\n            {\n                maxCPThreads = opts.ThreadPoolMaxIOCompletionThreads;\n                maxChanged = true;\n            }\n\n            // First try to set the max threads\n            var setMax = !maxChanged || ThreadPool.SetMaxThreads(maxThreads, maxCPThreads);\n\n            // Set the min threads\n            if (minChanged && !ThreadPool.SetMinThreads(minThreads, minCPThreads))\n                throw new Exception($\"Unable to call ThreadPool.SetMinThreads with {minThreads}, {minCPThreads}\");\n\n            // Retry to set max threads if it wasn't set in the earlier step\n            if (!setMax && !ThreadPool.SetMaxThreads(maxThreads, maxCPThreads))\n                throw new Exception($\"Unable to call ThreadPool.SetMaxThreads with {maxThreads}, {maxCPThreads}\");\n\n            opts.Initialize(loggerFactory);\n            StoreWrapper.DatabaseCreatorDelegate createDatabaseDelegate = (int dbId) =>\n                CreateDatabase(dbId, opts, clusterFactory, customCommandManager);\n\n            if (!opts.DisablePubSub)\n                subscribeBroker = new SubscribeBroker(null, opts.PubSubPageSizeBytes(), pubSubEpoch, startFresh: true, logger);\n\n            logger?.LogTrace(\"TLS is {tlsEnabled}\", opts.TlsOptions == null ? \"disabled\" : \"enabled\");\n\n            // Create Garnet TCP server if none was provided.\n            if (servers == null)\n            {\n                servers = new IGarnetServer[opts.EndPoints.Length];","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/host/GarnetServer.cs#L219-L255","documentation":"Thrown by GarnetServer.InitializeServer when ThreadPool.SetMinThreads returns false after the user configured ThreadPoolMinThreads or ThreadPoolMinIOCompletionThreads to non-zero values. The CLR rejects min thread values that exceed the current max thread limits, or are otherwise invalid. The error message includes the attempted values for diagnosis.","triggerScenarios":"Setting --thread-pool-min-threads or --thread-pool-min-io-completion-threads to values that are higher than the current max thread counts, or otherwise rejected by the runtime. The CLR requires min <= max for both worker and completion port threads.","commonSituations":"Setting min threads higher than max threads; containerized environments where the host has restrictive thread limits; configuring min threads without also setting max threads to accommodate.","solutions":["Ensure ThreadPoolMinThreads <= ThreadPoolMaxThreads and ThreadPoolMinIOCompletionThreads <= ThreadPoolMaxIOCompletionThreads.","If setting min threads, also set max threads to equal or higher values.","Reduce the min thread values to a valid range for your environment.","Check container host resource limits that may constrain the thread pool."],"exampleFix":"// before: min exceeds default max\nvar opts = new GarnetServerOptions\n{\n    ThreadPoolMinThreads = 500  // but max is default (~32767 on most systems, or lower in containers)\n};\n\n// after: set both consistently\nvar opts = new GarnetServerOptions\n{\n    ThreadPoolMinThreads = 200,\n    ThreadPoolMaxThreads = 500\n};","handlingStrategy":"validation","validationCode":"if (opts.ThreadPoolMinThreads > 0 || opts.ThreadPoolMinIOCompletionThreads > 0)\n{\n    ThreadPool.GetMaxThreads(out var maxWorker, out var maxIO);\n    if (opts.ThreadPoolMinThreads > maxWorker)\n        throw new InvalidOperationException($\"Min worker threads ({opts.ThreadPoolMinThreads}) exceeds max ({maxWorker})\");\n    if (opts.ThreadPoolMinIOCompletionThreads > maxIO)\n        throw new InvalidOperationException($\"Min IO threads ({opts.ThreadPoolMinIOCompletionThreads}) exceeds max ({maxIO})\");\n}","typeGuard":"static bool AreMinThreadSettingsValid(GarnetServerOptions opts)\n{\n    ThreadPool.GetMaxThreads(out var maxWorker, out var maxIO);\n    var minWorker = opts.ThreadPoolMinThreads > 0 ? opts.ThreadPoolMinThreads : 0;\n    var minIO = opts.ThreadPoolMinIOCompletionThreads > 0 ? opts.ThreadPoolMinIOCompletionThreads : 0;\n    return minWorker <= maxWorker && minIO <= maxIO;\n}","tryCatchPattern":null,"preventionTips":["Always set max threads >= min threads when configuring the thread pool.","Query current ThreadPool.GetMaxThreads before setting min values.","Avoid overriding thread pool settings unless you have measured a specific need."],"tags":["thread-pool","startup","configuration","resource-limits"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}