Java "unable to create native thread" (OutOfMemoryError) in CI
By Daniel Zoghalchali·Latchkey
This OutOfMemoryError is not about heap; the JVM could not create another OS thread. The runner hit a process/thread cap or ran out of memory for thread stacks.
What this error means
A Java step fails with OutOfMemoryError: unable to create new native thread, usually when launching many threads or parallel tasks. Lowering parallelism or using a larger runner clears it.
shell
java.lang.OutOfMemoryError: unable to create new native thread
at java.base/java.lang.Thread.start0(Native Method)
Common causes
A process/thread limit (ulimit / pids) was hit
The runner caps the number of threads/processes; exceeding it blocks new native threads.
Memory exhausted by thread stacks
Each thread reserves stack memory; thousands of threads can exhaust RAM on a tight runner.
How to fix it
Lower thread/task parallelism
Reduce the thread pool or build parallelism so fewer native threads are needed.
shell
./gradlew test --max-workers=2
# inspect limits
ulimit -u
Add headroom
Run on a runner with more RAM and higher process limits.
Shrink per-thread stack size (-Xss) if appropriate.
Cap thread pools in the application.
How to prevent it
Bound thread pools and build parallelism.
Right-size memory/process limits for thread-heavy jobs.
Watch ulimit -u on constrained runners.
Frequently asked questions
What causes "unable to create native thread"?
The runner caps the number of threads/processes; exceeding it blocks new native threads.
How do I fix unable to create native thread?
Reduce the thread pool or build parallelism so fewer native threads are needed.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.