Symptoms
Captions stop and Jigasi can no longer start threads. Issue #615 contains these exact log fragments, including a WebSocket thread name: [S1]
Failed to start thread "Unknown thread" - pthread_create failed (EAGAIN)
Failed to start the native thread for java.lang.Thread "WebSocket@1015685120-8400"
java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reachedOne contributor reported roughly 170 MB of heap use but 25,000 threads after failed Whisper connections. That is a thread-growth report, not evidence that every installation needs a larger heap. A separate heap-exhaustion message is java.lang.OutOfMemoryError: Java heap space. [S1][S7]
Cause
EAGAIN can indicate insufficient resources or a thread/process limit. Native stacks and other process memory sit outside the Java heap. A container can run out of resources while its heap remains small. Compare threads, resident memory and heap usage together. [S5][S6][S7]
Jigasi’s launcher defaults JIGASI_MAX_MEMORY to 3072m and passes it through -Xmx, about 3 GiB of maximum heap. Stock stable-11248/transcriber.yml does not forward this variable. Putting it only in .env therefore does not override the launcher. [S3][S4]
The maintainer recommended at least 3.5 GB for the container around the default heap, rather than a 2 GB container limit. This is a starting allocation, not a guaranteed capacity. In the failure report, the maintainer also identified repeated Whisper 403 errors and asked the operator to fix them. [S1]
Whisper PR #619 merged December 9, 2025. It stops failed WebSocket clients, limits connection attempts and adds a timeout. Its code is present in released Jigasi 1.1-415-g2750d54-1. Later Vosk reports in #615 remain unresolved. PR #650 targets graceful Whisper shutdown and transcript completion, is still open, and is not a released fix for this issue. [S1][S2][S8]
Fix
-
Docker stable-11248: capture measurements before restarting. Include your existing overlays in this helper. The stock transcriber has one Java process; these commands select it. UID 1000 matches the rootless process. [S3][S5][S9]
Terminaldc() { docker compose -f docker-compose.yml -f transcriber.yml "$@" } dc logs --tail=200 transcriber dc exec -T --user 1000:1000 transcriber sh -lc ' pid=$(pgrep -o -x java) test -n "$pid" || exit 1 grep -E "^(Threads|VmRSS|VmSize):" "/proc/$pid/status" jcmd "$pid" GC.heap_info jcmd "$pid" VM.flags ' docker inspect --format 'Memory={{.HostConfig.Memory}} PidsLimit={{.HostConfig.PidsLimit}} OOMKilled={{.State.OOMKilled}}' "$(dc ps -q transcriber)"Threadscounts native threads.VmRSSis resident memory; heapusedis not total process memory. Repeat measurements after meetings end. Sustained growth in idle thread counts is stronger evidence of a leak than one large busy snapshot. [S1][S5][S6] -
Docker: update older Whisper installations and repair backend failures.
stable-11248remains latest as checked October 6, 2026. Obtain matching release files following the upgrade guide, setJITSI_IMAGE_VERSION=stable-11248in.envand rundc pullbefore recreation. Inspect withdc exec -T transcriber dpkg-query -W jigasi; released1.1-415-g2750d54-1contains PR #619. Investigate backend403responses using the Whisper setup. Larger limits do not repair authorization. [S1][S2][S3] -
Docker stable-11248: forward the heap setting and leave native headroom. In
.env, set: [S3][S4]dotenvJIGASI_MAX_MEMORY=3072mCreate this guide-specific overlay,
transcriber-memory.yml: [S3][S10]YAMLservices: transcriber: environment: - JIGASI_MAX_MEMORY mem_limit: 4gThis 4 GiB example exceeds the maintainer’s minimum; reserve host memory for other services and the speech backend. Update the helper, validate and recreate outside active sessions: [S1][S9][S10]
Terminaldc() { docker compose -f docker-compose.yml -f transcriber.yml -f transcriber-memory.yml "$@" } dc config --quiet dc up -d --force-recreate transcriberDo not copy the issue’s experimental
-Xss256k,pids_limit: 8192ornprocchanges as a leak fix. They were operator experiments, not a maintainer-approved recipe. Raising a task ceiling can merely postpone exhaustion. [S1][S6] -
Debian/Ubuntu Jigasi packages: measure the service. These steps cover
1.1-415-g2750d54-1. Use a matching JDK’sjcmd; the Docker image includes JDK 21, while your package runtime may differ. [S4][S5][S9]Terminalpid=$(systemctl show jigasi -p MainPID --value) test "$pid" -gt 0 || exit 1 sudo grep -E '^(Threads|VmRSS|VmSize):' "/proc/$pid/status" sudo -u jigasi jcmd "$pid" GC.heap_info sudo -u jigasi jcmd "$pid" VM.flags systemctl show jigasi -p TasksCurrent -p TasksMax -p LimitNPROC -p MemoryCurrent -p MemoryMaxEdit
/etc/jitsi/jigasi/config, preserving other assignments. SetJIGASI_MAX_MEMORY=3072m, or a measured allocation your host supports, then runsudo systemctl restart jigasi. The unit reads this file and setsTasksMax=65000andLimitNPROC=65000; inspect local overrides. For older packages with the Jitsi repository configured, update and verify: [S2][S4][S11][S13]Terminalsudo apt-get update sudo apt-get install --only-upgrade jigasi dpkg-query -W jigasi -
Both installations: size by measured concurrent load. No universal safe participants-per-Jigasi figure was established. Test simultaneous rooms, speakers, long sessions and backend failures. Add instances before resource saturation, with working brewery registration and backend capacity. Jicofo can select among registered transcribers using load and region preferences. More instances distribute new work; they do not cure leaking connections. [S1][S12]
Verify
For Docker, run dc exec -T transcriber printenv JIGASI_MAX_MEMORY. The example must print exactly 3072m. Inspect memory with docker inspect --format 'Memory={{.HostConfig.Memory}} OOMKilled={{.State.OOMKilled}}' "$(dc ps -q transcriber)". The healthy example prints: [S3][S10]
Memory=4294967296 OOMKilled=falseFor either installation, VM.flags should contain -XX:MaxHeapSize=3221225472 for this heap allocation. Then repeat start/speak/leave cycles and compare idle thread counts. Require working captions, no recurring backend failures and no continuing idle thread growth. These are acceptance checks, not load-test results from our server. [S2][S4][S5]
If it still fails
Capture jcmd "$pid" Thread.print as the JVM user before restarting. Use the same container or package context as above. Thread dumps help identify accumulating WebSocket pools; a small heap dump alone misses that evidence. [S1][S5]
Read Docker transcriber logs, or /var/log/jitsi/jigasi.log and sudo journalctl -u jigasi -n 200 --no-pager for packages. Check backend errors and effective task limits. On cgroup v2, pids.events records task-limit hits and memory.events records memory events; inspect the actual service/container cgroup rather than assuming a host path. [S4][S6][S11]
Use transcription troubleshooting if original captions never work, or the Vosk guide for backend setup. [S1]
FAQ
Will increasing Java heap fix EAGAIN?
Only if the measurements justify it. Thousands of retained threads with a small heap require connection cleanup and task/native-memory investigation. [S1][S6]
Why does my .env heap setting do nothing?
Stock stable-11248/transcriber.yml omits JIGASI_MAX_MEMORY. Explicitly forward it and recreate the container. [S3][S4]
Is this fixed upstream?
The Whisper failure-path fix is PR #619. The Vosk report remains unresolved as of October 6, 2026; PR #650 is still open and concerns a separate shutdown problem. [S1][S2][S8]
Sources
[S1] Issue #615, November 2025 to July 2026, community reports and maintainer comments; memory recommendation, backend diagnosis, maintainer comments.
[S2] Whisper PR #619, merged December 9, 2025, repository fix; released Whisper code, September 11, 2026, source code.
[S3] Transcriber Compose, source code; latest release, September 14, 2026, release note; package index, checked October 6, 2026, official repository; Docker handbook, official doc.
[S4] Jigasi launcher, packaged service, September 11, 2026, source code.
[S5] JDK 21 jcmd, matching diagnostic tools, checked October 6, 2026, official docs.
[S6] Thread creation limits, process status fields, official Linux manuals; cgroup v2 controllers, official kernel doc, checked October 6, 2026.
[S7] Diagnosing Java memory failures, checked October 6, 2026, official doc.
[S8] Whisper PR #650, September 25, 2026, proposed change, open as checked October 6, 2026; released Vosk client, September 11, 2026, source code.
[S9] Docker JDK installation, process tools, September 14, 2026, source code; pgrep, official Linux manual; rootless PR #2258, repository change.
[S10] Compose service limits, container inspection, Compose commands, checked October 6, 2026, official docs.
[S11] systemctl, journalctl, task and memory controls, official docs; Jigasi logs, source code, checked October 6, 2026.
[S12] Jicofo transcriber selection, September 2026, source code.
[S13] APT upgrade options, package query, official Debian manuals; Jitsi repository, official doc, checked October 6, 2026.
Open questions
No real-server thread-leak reproduction or capacity benchmark was run. The first Docker release shipping PR #619 was not established; its inclusion in the cited Jigasi release was verified. The Vosk error-path report is not fixed as of 2026-10-06. If you need measured capacity or multiple-instance setup, our transcription service can scope that work. [S1][S2]