# Java "unable to create new native thread" / OOM Thread in CI

> Fix "java.lang.OutOfMemoryError: unable to create new native thread" in CI - the process hit the OS thread/ulimit or ran out of native memory for thread stacks, not Java heap.

Source: https://latchkey.dev/learn/java-jvm/jvm-unable-to-create-native-thread  
Updated: 2026-06-25

The JVM could not create another OS thread. Despite the OutOfMemoryError name, this is not Java heap - it is the OS refusing more threads (ulimit/pid cap) or no native memory left for thread stacks.

## Diagnose it: JDK version and heap

```Terminal
java -version 2>&1
echo "JAVA_HOME=$JAVA_HOME"
free -h

# class file 65 = Java 21, 61 = Java 17, 55 = Java 11
javap -verbose <SomeClass>.class | grep "major version"
```

> An unsupported class file version is a JDK mismatch, not a code error. Exit 137 during a build is the out-of-memory killer, which no JVM flag in the build file will explain.

## FAQ

### What causes Java "unable to create new native thread" / OOM thread in CI?

There are 2 common causes: os thread/process limit reached and native memory exhausted by thread stacks. The container or user hit ulimit -u (max processes/threads) or a cgroup pids limit.

### How do I fix Java "unable to create new native thread" / OOM thread in CI?

There are 2 fixes depending on which cause you have: raise the os thread/process limit and reduce thread usage and stack size. Work through them in order, since the first is the most common.

### What does Java "unable to create new native thread" / OOM thread in CI actually mean?

The application or test framework fails with java.lang.OutOfMemoryError: unable to create new native thread, typically after spawning many threads (thread pools, parallel tests, connection pools).

### How do I stop Java "unable to create new native thread" / OOM thread in CI happening again?

Use bounded thread pools sized to the workload. The prevention section lists 3 changes that keep it from recurring.

### 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.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
