CI "OutOfMemoryError: unable to create new native thread" (JVM)
Despite the OutOfMemoryError name, this is rarely about Java heap. The JVM could not create an OS thread - either the runner hit a thread/process limit (ulimit -u/pids.max) or there was no memory left for the new thread’s native stack.
What this error means
A JVM build or test (Gradle, Maven, a Java app) fails with java.lang.OutOfMemoryError: unable to create new native thread. Raising -Xmx does not help, because the exhausted resource is OS threads or native memory, not the managed heap.
java.lang.OutOfMemoryError: unable to create new native thread
at java.base/java.lang.Thread.start0(Native Method)Common causes
The process/thread limit was reached
The JVM (and its tooling) spawns many threads. Hitting ulimit -u or the cgroup pids.max means the OS refuses to create another thread, surfacing as this OutOfMemoryError.
No native memory left for thread stacks
Each thread reserves a native stack outside the heap. A very large -Xmx plus many threads can leave too little address space/RAM for new stacks, so thread creation fails.
How to fix it
Inspect thread limits and counts
ulimit -u # max user processes/threads
cat /sys/fs/cgroup/pids.max # container pid/thread ceiling
ps -eLf | wc -l # threads currently runningRaise the limit or reduce thread/heap pressure
- Raise
ulimit -u(or the containerpidslimit) for the step if the work needs many threads. - Lower build/test thread counts (Gradle
--max-workers, test fork counts). - If
-Xmxis very large, reduce it so more address space/RAM is left for native thread stacks.
How to prevent it
- Set a generous process/thread limit on runners for JVM workloads.
- Bound build and test parallelism to the runner’s capacity.
- Balance
-Xmxagainst the runner’s total memory so native stacks have room.