Summary
Maestro Android execution on a physical device consistently fails with native thread exhaustion in the Android forwarding path.
This reproduces across hosts and across two adjacent CLI versions, and reproduces with direct maestro test invocation outside our wrapper script.
Classification
- Status:
HARNESS_DEFECT
- Reason:
maestro_native_thread_failure
- Signature:
pthread_create_or_eagain
Environment
- Host OS: macOS (Darwin 24.6.0)
- Java: Temurin OpenJDK 17.0.18
- Maestro CLI tested: 2.3.0 and 2.4.0
- Device: Samsung SM_G981U
- Device serial: RFCN200GA3F
Reproduction
- Ensure device is visible:
adb devices -l shows RFCN200GA3F device
- Apply reverse bindings:
adb -s RFCN200GA3F reverse tcp:7001 tcp:7001
adb -s RFCN200GA3F reverse tcp:8081 tcp:8081
- Run direct Maestro command (outside wrapper):
maestro --device RFCN200GA3F test .maestro/_harness-admission-smoke.yaml --no-reinstall-driver
Also reproduced with isolated 2.4.0 binary from release artifact:
/tmp/maestro-cli-2.4.0/maestro/bin/maestro --device RFCN200GA3F test .maestro/_harness-admission-smoke.yaml --no-reinstall-driver
Observed failure signatures
pthread_create failed (EAGAIN)
OutOfMemoryError: unable to create native thread
- stack includes
dadb.forwarding.TcpForwarder
- gRPC
DEADLINE_EXCEEDED
Representative stack frames include:
dadb.forwarding.TcpForwarder.handleForwarding(TcpForwarder.kt:63)
maestro.drivers.AndroidDriver.deviceInfo(...)
maestro.orchestra.Orchestra.runFlow(...)
Additional observations
- Reproduces cross-host (Mini + laptop).
- Reproduces outside harness wrapper (direct Maestro invocation), so not wrapper-only.
- Device visibility and reverse bindings are healthy before failure.
- Constrained JVM probe did not resolve issue:
JAVA_TOOL_OPTIONS='-Xss256k -XX:ActiveProcessorCount=2'
- Failure shape remained materially the same.
Limits snapshot from failing environment
ulimit -u: 1392
ulimit -n: 1048575
launchctl limit maxproc: 2048 soft / 2500 hard
launchctl limit maxfiles: 256 soft / unlimited hard
Expected behavior
Maestro should execute the flow on the connected physical Android device without exhausting native threads in forwarding setup.
Actual behavior
Execution starts, then fails during Android forwarding/runtime initialization with native thread creation failures and gRPC timeout.
Summary
Maestro Android execution on a physical device consistently fails with native thread exhaustion in the Android forwarding path.
This reproduces across hosts and across two adjacent CLI versions, and reproduces with direct
maestro testinvocation outside our wrapper script.Classification
HARNESS_DEFECTmaestro_native_thread_failurepthread_create_or_eagainEnvironment
Reproduction
adb devices -lshowsRFCN200GA3F deviceadb -s RFCN200GA3F reverse tcp:7001 tcp:7001adb -s RFCN200GA3F reverse tcp:8081 tcp:8081maestro --device RFCN200GA3F test .maestro/_harness-admission-smoke.yaml --no-reinstall-driverAlso reproduced with isolated 2.4.0 binary from release artifact:
/tmp/maestro-cli-2.4.0/maestro/bin/maestro --device RFCN200GA3F test .maestro/_harness-admission-smoke.yaml --no-reinstall-driverObserved failure signatures
pthread_create failed (EAGAIN)OutOfMemoryError: unable to create native threaddadb.forwarding.TcpForwarderDEADLINE_EXCEEDEDRepresentative stack frames include:
dadb.forwarding.TcpForwarder.handleForwarding(TcpForwarder.kt:63)maestro.drivers.AndroidDriver.deviceInfo(...)maestro.orchestra.Orchestra.runFlow(...)Additional observations
JAVA_TOOL_OPTIONS='-Xss256k -XX:ActiveProcessorCount=2'Limits snapshot from failing environment
ulimit -u: 1392ulimit -n: 1048575launchctl limit maxproc: 2048 soft / 2500 hardlaunchctl limit maxfiles: 256 soft / unlimited hardExpected behavior
Maestro should execute the flow on the connected physical Android device without exhausting native threads in forwarding setup.
Actual behavior
Execution starts, then fails during Android forwarding/runtime initialization with native thread creation failures and gRPC timeout.