{"record":{"id":"ac54682e7d27d59e","repo":"redis/redis","slug":"fatal-failed-to-start-thread-d","errorCode":null,"errorMessage":"FATAL: Failed to start thread %d.\n","messagePattern":"FATAL: Failed to start thread (.+?)\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/redis-benchmark.c","lineNumber":951,"sourceCode":"    }\n}\n\nstatic void initBenchmarkThreads(void) {\n    int i;\n    if (config.threads) freeBenchmarkThreads();\n    config.threads = zmalloc(config.num_threads * sizeof(benchmarkThread*));\n    for (i = 0; i < config.num_threads; i++) {\n        benchmarkThread *thread = createBenchmarkThread(i);\n        config.threads[i] = thread;\n    }\n}\n\nstatic void startBenchmarkThreads(void) {\n    int i;\n    for (i = 0; i < config.num_threads; i++) {\n        benchmarkThread *t = config.threads[i];\n        if (pthread_create(&(t->thread), NULL, execBenchmarkThread, t)){\n            fprintf(stderr, \"FATAL: Failed to start thread %d.\\n\", i);\n            exit(1);\n        }\n    }\n    for (i = 0; i < config.num_threads; i++)\n        pthread_join(config.threads[i]->thread, NULL);\n}\n\nstatic void benchmark(const char *title, char *cmd, int len) {\n    client c;\n\n    config.title = title;\n    config.requests_issued = 0;\n    config.requests_finished = 0;\n    config.previous_requests_finished = 0;\n    config.last_printed_bytes = 0;\n    hdr_init(\n        CONFIG_LATENCY_HISTOGRAM_MIN_VALUE,  // Minimum value\n        CONFIG_LATENCY_HISTOGRAM_MAX_VALUE,  // Maximum value","sourceCodeStart":933,"sourceCodeEnd":969,"githubUrl":"https://github.com/redis/redis/blob/4f20cb48934463db5970bd476461b2d57af3f38d/src/redis-benchmark.c#L933-L969","documentation":"startBenchmarkThreads calls pthread_create for worker i; if it returns non-zero the benchmark prints 'FATAL: Failed to start thread %d.' and exit(1). The OS refused to spawn another thread.","triggerScenarios":"pthread_create(&(t->thread), NULL, execBenchmarkThread, t) returns non-zero at src/redis-benchmark.c:950. Caused by EAGAIN (RLIMIT_NPROC / kernel.threads-max / cgroup pid limit hit) or ENOMEM (stack allocation failure).","commonSituations":"--threads set very high, low ulimit -u in the shell, container with a small pids limit, very large -c combined with --threads so per-thread client count explodes, memory pressure preventing stack allocation.","solutions":["Lower --threads (start with 1-4 per CPU core)","Raise the limit: ulimit -u unlimited (or nproc in systemd unit)","For containers, raise pids.max (docker --pids-limit) and check kernel.threads-max","Check dmesg for 'cgroup out of memory' or pthread EAGAIN reports"],"exampleFix":"// before\nredis-benchmark --threads 500 -c 500 -n 1000000\n// after\nulimit -u\nulimit -u 65536\nredis-benchmark --threads 8 -c 50 -n 1000000","handlingStrategy":"validation","validationCode":"# Pre-flight: ensure we can spawn the requested thread count\nulimit -u                     # RLIMIT_NPROC\n[ \"$(ulimit -u)\" -ge $((THREADS * 4)) ] || { echo 'raise ulimit -u' >&2; exit 1; }\n# Container check\ngrep -E 'pids\\.max|^pids' /sys/fs/cgroup/pids.max 2>/dev/null || true\n","typeGuard":null,"tryCatchPattern":"# Cannot recover inside the tool (it exits); catch at the shell and retry with fewer threads\nif ! redis-benchmark --threads \"$THREADS\" -c \"$C\" -n \"$N\"; then\n  echo \"thread spawn failed; retrying with fewer threads\" >&2\n  THREADS=$(( THREADS / 2 ))\n  redis-benchmark --threads \"$THREADS\" -c \"$C\" -n \"$N\"\nfi","preventionTips":["Keep --threads modest (start at #physical-cores, not hundreds)","Raise ulimit -u (or systemd LimitNPROC) in the benchmark's shell/unit","In containers, raise pids.max and check kernel.threads-max","Avoid combining very high -c with high --threads"],"tags":["threads","pthread","resources","ulimit","fatal"],"backgroundTag":null,"analyzedSha":"4f20cb48934463db5970bd476461b2d57af3f38d","analyzedAt":"2026-08-10T14:17:07.821Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}