Why does JVB fail every conference join with dcsctp4j NoClassDefFoundError?

Short answer

The native library is bundled in a JAR, but the old 16 MiB /run tmpfs can be too small to extract it. [S2] Upgrade to stable-11248 with its Compose files, or change the Java containers' /run mount to size=32M,mode=1750,exec and recreate them. [S3][S4] A noexec Java/JNA temp directory is a separate loading failure; the checked JVB launchers already point both temp properties at /run/jvb/tmp. [S5][S6]

Symptoms

On ghcr.io/jitsi/jvb:stable-11146-2, issue #2323 reports this JVB exception when an endpoint requests SCTP transport. The application needs native code for that transport. [S1]

Text
java.lang.NoClassDefFoundError: Could not initialize class org.jitsi.dcsctp4j.DcSctpOptions
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.UnsatisfiedLinkError: no dcsctp4j in java.library.path: /usr/java/packages/lib:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
    at org.jitsi.dcsctp4j.DcSctp4j.<clinit>(DcSctp4j.java:36)
    at org.jitsi.dcsctp4j.DcSctpOptions.<clinit>(DcSctpOptions.java:27)
    at org.jitsi.videobridge.dcsctp.DcSctpTransport.DEFAULT_SOCKET_OPTIONS_delegate$lambda$0(DcSctpTransport.kt:123)

The reported conference-modify request fails. Jicofo then logs: [S1]

Text
WARNING: BridgeSelector.selectBridge#186: There are no operational bridges.
SEVERE: ParticipantInviteRunnable.doRun#216: Can not invite participant, no bridge available.

For users, conference entry fails for guests and moderators, not merely a feature using data channels. These Jicofo messages alone do not establish this cause; match the JVB exception too. [S1]

Cause

The native library was not missing from the image. The reporter found linux-x86-64/libdcsctp4j.so inside jitsi-dcsctp-1.0-7-gb548df2.jar. Searching only for loose .so files missed it. A maintainer measured the extracted library at 15.53 MiB, almost the entire old 16 MiB /run limit. PR #2325 raised that limit to 32M. [S2][S3]

There are two distinct constraints: enough writable space for extraction, and a mount that permits executable mappings. PR #2263 selected /run/jvb/tmp because /tmp was deliberately noexec. Both checked launchers, stable-11146-2 and stable-11248, set -Djava.io.tmpdir=/run/jvb/tmp and -Djna.tmpdir=/run/jvb/tmp. Adding those flags again does not enlarge /run. [S5][S6]

The thread’s initial noexec diagnosis should not replace its final size fix. Upstream kept /tmp non-executable and changed /run capacity. The fix covers JVB, Jicofo, Jigasi and the transcriber Compose definitions. A tmpfs size is a ceiling, not memory allocated in full at startup. [S2][S3][S10]

Fix

Docker: stable-11146-2 to stable-11248

  1. Record the current images and arrange a maintenance window. From your existing Compose project, run: [S8]

    Terminal
    docker compose images

    Back up your deployment files and persistent configuration using the handbook update procedure. Recreating services can interrupt meetings. [S7][S8]

  2. Upgrade both images and release files. stable-11248, released 2026-09-14, remains the latest release checked on 2026-10-05. Its release notes include PR #2325. Use its docker-compose.yml, plus matching overlay files you actually use. Merge your custom changes rather than keeping the old tmpfs definitions. [S3][S4][S7]

    Set this existing image selector in .env, replacing any older pin: [S7]

    dotenv
    JITSI_IMAGE_VERSION=stable-11248

    Changing that variable alone does not update mount options in an old Compose file. [S7]

  3. Alternatively, patch the mount size. For a stable-11146-2 workaround, replace the tmpfs blocks under the existing jvb and jicofo services with this exact upstream configuration. This is a fragment, not a replacement for the entire Compose file. [S3][S7]

    YAML
    services:
      jvb:
        tmpfs:
          - /run:size=32M,mode=1750,exec
          - /tmp:size=16M,mode=1777,noexec
      jicofo:
        tmpfs:
          - /run:size=32M,mode=1750,exec
          - /tmp:size=16M,mode=1777,noexec

    If using Jigasi or the transcriber overlay, change its /run line to the same 32M line. Their upstream /tmp entries remain size=128M,mode=1777,noexec. The merged fix did not add uid=1000,gid=1000 or require 128M for /run. [S3]

  4. Validate and recreate. For the full release upgrade, run the following with your normal Compose file selection: [S8]

    Terminal
    docker compose config -q
    docker compose pull
    docker compose up -d --force-recreate

    For only the temporary JVB/Jicofo mount patch, recreate those services: [S8]

    Terminal
    docker compose up -d --no-deps --force-recreate jvb jicofo

Custom Compose and Kubernetes

For either checked Docker tag, the same storage requirements apply when running these images outside upstream Compose. An image upgrade cannot modify your host Compose mounts or Kubernetes volumes. Review any overridden launcher or temp properties too. [S6][S7][S9]

In Kubernetes, provide writable, executable temp storage with adequate capacity. A memory-backed emptyDir uses medium: Memory; sizeLimit: 32Mi expresses the upstream capacity in Kubernetes units. Account for that usage in container memory limits. This is a deployment translation, not a Kubernetes fix tested in #2323; inspect actual permissions and mount flags. [S3][S9]

Debian/Ubuntu packages

The 32M fix changes Docker Compose, not the Debian package. For package installations using the JVB service layout reviewed at stable/jitsi-meet_11248, inspect the real exception and local temp configuration first. The unit reads /etc/jitsi/videobridge/config and writes application output to /var/log/jitsi/jvb.log. [S3][S11]

Terminal
sudo tail -n 200 /var/log/jitsi/jvb.log
sudo cat /etc/jitsi/videobridge/config

The launcher passes JAVA_SYS_PROPS to Java. If your local hardening redirects temp storage to a small or non-executable mount, correct that mount or temp location. No package-specific affected version or upgrade fix was established by this Docker issue. [S5][S11][S12]

Verify

For Docker after either fix, check the actual /run capacity: [S7][S8][S12]

Terminal
docker compose exec -T jvb df --output=size -k /run | tail -n 1 | tr -d ' '

For the exact 32M mount, the expected output is: [S7][S12]

Text
32768

This proves capacity, not native-library loading. Start a fresh conference on https://meet.example.com with three participants so the test exercises the bridge, then read current logs: [S8][S13]

Terminal
docker compose logs --since 5m jvb jicofo

Successful entry and working media, without the quoted JVB initialization failure, are the functional check. There is no universal success log line established by the thread; do not treat container startup alone as proof. [S1][S2]

If it still fails

For Docker, inspect the runtime mount flags, usage and launch script: [S6][S8][S12][S14]

Terminal
docker compose exec jvb cat /proc/mounts
docker compose exec jvb du -sh /run
docker compose exec jvb cat /etc/s6-overlay/scripts/jvb

Check for noexec on the actual temp mount, capacity exhaustion, or replaced JVM flags. Capture the earliest native-loading exception. A later Could not initialize class message may hide the original failure. [S2][S5][S6]

Do not disable SCTP as the repair. The reporter tried videobridge.sctp.enabled = false and received feature-not-implemented: SCTP support is not configured, still preventing joins. [S1]

FAQ

Is the native library absent?

Not in the investigated image. It was bundled in the JAR and needed extraction space. [S2]

Is increasing Java heap enough?

No. PR #2325 changes the filesystem’s tmpfs ceiling, not Java heap settings. [S3]

Must I make /tmp executable?

No. Upstream keeps /tmp noexec and uses executable /run temp storage. [S5][S7]

Why does upgrading the image alone still fail?

Your old deployment file can retain the 16M mount. Update the mount definition and recreate the container. [S7][S8]

Sources

[S1] Issue #2323, 2026-09-11, community report, error text and failed workarounds.

[S2] Issue #2323 discussion, 2026-09-11, community investigation and subsequent maintainer comments, including extracted size and 32M decision.

[S3] PR #2325 and diff, merged 2026-09-11, source code and maintainer approval.

[S4] stable-11248 notes and latest release API, 2026-09-14, checked 2026-10-05, release note.

[S5] PR #2263 and stable-11146 notes, June/August 2026, maintainer explanation and release note.

[S6] JVB launchers: stable-11146-2, stable-11248, checked 2026-10-05, source code.

[S7] stable-11248 Compose and Docker handbook, checked 2026-10-05, source code and official doc.

[S8] Docker Compose config, images, pull, up, exec, logs, checked 2026-10-05, official doc.

[S9] Kubernetes emptyDir, checked 2026-10-05, official doc.

[S10] Docker tmpfs mounts, checked 2026-10-05, official doc.

[S11] JVB package service and launcher, release 11248, checked 2026-10-05, source code.

[S12] GNU Coreutils manual, checked 2026-10-05, official doc, diagnostic command syntax.

[S13] Jitsi Meet config.js, release 11248, checked 2026-10-05, source code, peer-to-peer and bridge switching.

[S14] Linux /proc filesystem, checked 2026-10-05, official doc, mount information.

Open questions

These steps were source-reviewed, not tested on a live Jitsi server. The thread does not establish that every architecture fails, nor provide a validated Kubernetes manifest or package-specific regression. A continuing failure needs its first exception and actual mount configuration. [S1][S2][S3]

Collect debug info

These commands gather what an engineer needs to diagnose a Jitsi server. Copy them, run them, and keep the output.

Terminal
# Run on the server, from your docker-jitsi-meet folder

# 1. Every service should be "running" (or "healthy")
docker compose ps

# 2. Which images and release tags are running
docker compose images

# 3. Recent logs from the core services
docker compose logs --tail=200 web prosody jicofo jvb

# 4. The settings most fixes depend on
grep -E '^(PUBLIC_URL|JVB_ADVERTISE_IPS|ENABLE_LETSENCRYPT|ENABLE_AUTH|AUTH_TYPE)=' .env

# 5. Is anything listening for media on UDP 10000?
sudo ss -ulnp | grep 10000

Installed with the Debian packages instead of Docker? Read the service logs with:

Terminal
sudo journalctl -u prosody -u jicofo -u jitsi-videobridge2 --since "1 hour ago"

Remove passwords, secrets and tokens before you share any output.

Send the output to an engineer

Stuck, or would rather not do this by hand?

Deploy it in one click

A private Jitsi server in your own AWS account with SSL, your domain and optional recording, transcription and JWT. Free 15 minute trial.

Start free trial

Talk to a Jitsi engineer

Setup, fixes, branding, recording, scaling. Tell us what is happening and we reply with a plan and a quote.

Get expert help

Related

Recently updated