Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/openlibrecommunity/olcrtc/llms.txt

Use this file to discover all available pages before exploring further.

This page covers the most common runtime issues with olcRTC, how to diagnose them, and what to change in your configuration to fix them.
Enable debug: true in your YAML config as the first step when diagnosing any connection issue. This produces verbose logs from the engine, transport, and session layers that usually point directly to the problem.
debug: true

Symptom: olcRTC exits immediately with key required or invalid key.Cause: The crypto.key field is missing, empty, or not a valid 64-character hex string. The key must be the same on both the server (mode: srv) and client (mode: cnc).Fix:
  1. Generate a valid key:
    openssl rand -hex 32
    
    This produces exactly 64 hex characters (32 bytes).
  2. Set the key in both YAML files:
    crypto:
      key: "aabbccdd..."  # exactly 64 hex chars
    
  3. Alternatively, store the key in a file and reference it:
    crypto:
      key_file: /etc/olcrtc/my.key
    
    Do not set both crypto.key and crypto.key_file at the same time.
  4. Verify both sides use the identical key string.
Symptom: The client starts, appears to connect, but nothing listens on the expected SOCKS5 port. curl --socks5-hostname 127.0.0.1:8808 ... fails with “connection refused”.Cause: One or more of the following:
  • The YAML is configured as mode: srv instead of mode: cnc
  • socks.host or socks.port are wrong
  • The process exited before binding (check logs)
Fix:
  1. Confirm the client YAML has mode: cnc:
    mode: cnc
    
  2. Confirm the SOCKS5 fields are set:
    socks:
      host: "127.0.0.1"
      port: 8808
    
  3. Check the logs for errors during startup. With debug: true you will see a log line when SOCKS5 begins listening.
  4. If you set socks.host to a non-loopback address (anything other than 127.0.0.1, ::1, or localhost), you must also set socks.user and socks.pass. olcRTC enforces this to prevent accidentally exposing an open proxy on the network:
    socks:
      host: "0.0.0.0"
      port: 8808
      user: myuser
      pass: mypassword
    
Symptom: Both srv and cnc start with the Jitsi provider, but neither side establishes the tunnel. The logs show waiting for peer in room indefinitely.Cause: Jitsi’s Jicofo conference controller only sends a Jingle session-initiate once at least two participants are present in the same MUC room. A single olcRTC instance sitting alone in the room will wait forever for Jicofo to start the Jingle negotiation.Fix:
  1. Make sure both srv and cnc are running and pointed at the same room ID (the same https://host/room URL).
  2. Both sides must start within a reasonable time of each other. After the XMPP/BOSH session idle timeout (~60 seconds), Prosody may close the connection if no traffic is exchanged. olcRTC’s internal XMPP keepalive (ping every 25 seconds) prevents this, but only while the process is running.
  3. If you start the server and wait a long time before starting the client, Jicofo may have already cleaned up the empty conference. Restart the server if needed.
Always verify which Jitsi server is reachable in your network by opening the instance URL in a browser. If the page does not load, that server is blocked. See docs/examples/jitsi.instances.yaml in the repository for a list of public instances.
Symptom: The tunnel appears to connect (cnc and srv both show they are up), but no data flows. SOCKS5 connections time out immediately.Cause: In the normal WbStream guest flow, access tokens are issued with canPublishData=false. The SCTP data channel opens successfully, but the SFU does not route data through it. The tunnel is structurally up but silently drops all payload.Fix (option A — change transport):Switch to a transport that does not require data channel publish rights:
net:
  transport: vp8channel   # or seichannel or videochannel
This is the recommended approach for most users.Fix (option B — use a moderator token):If you have a WbStream account with moderator rights, set auth.token to your account token on both sides:
auth:
  provider: wbstream
  token: "<your-account-token-with-canPublishData=true>"
To grant moderator in the WbStream UI: open the participants list → click the three dots next to the entry → press Moderator (required on both server and client sides).In the guest flow, the obtained guest token is logged once at startup — you can copy it into auth.token to reuse the same identity on the next run.
Symptom: The log shows seichannel ack timeout repeatedly. The PeerConnection is formally alive, but no data gets through.Cause: The provider is throttling, delaying, or not routing the H.264 video stream carrying the SEI NAL payloads. This is especially common on self-hosted Jitsi instances where Jicofo periodically cuts or delays upstream video when there is no active video receiver in the room (from Jicofo’s perspective, the sender is sending video but nobody is watching it).Fix:
  1. Change transport. Switch to datachannel (for Jitsi) or vp8channel (for WbStream or Telemost):
    net:
      transport: vp8channel
    
  2. Change provider. If you need seichannel, use wbstream — it is the most stable provider for SEI-based transport.
  3. Note that seichannel is not supported by Telemost at all (fails E2E tests). Do not use this combination.
Symptom: videochannel transport fails to start with an error like exec: "ffmpeg": executable file not found in $PATH.Cause: The videochannel transport requires ffmpeg to encode video frames. It is not bundled with olcRTC.Fix:
  1. Install ffmpeg using your system package manager:
    # Debian/Ubuntu
    apt install ffmpeg
    
    # Alpine
    apk add ffmpeg
    
    # macOS
    brew install ffmpeg
    
  2. Or specify the full path to the ffmpeg binary in your YAML:
    ffmpeg: /usr/local/bin/ffmpeg
    
  3. Also note: the tile codec for videochannel requires a resolution of exactly 1080×1080:
    video:
      codec: tile
      width: 1080
      height: 1080
    
Symptom: The tunnel works but is noticeably slower or has higher latency than expected.Cause and fixes:
  1. Transport choice. Speed ranking from fastest to slowest: datachannel > vp8channel > seichannel > videochannel. Switch to the fastest transport that works for your provider.
  2. vp8channel batch/fps settings. Tune the batch size and FPS for throughput:
    vp8:
      fps: 30       # lower FPS reduces CPU load
      batch_size: 64  # larger batch = more data per tick = higher throughput
    
  3. traffic.max_payload_size. If set, this limits the encrypted message size. Larger values allow more data per message:
    traffic:
      max_payload_size: 0   # 0 = use transport default (no limit)
    
  4. traffic pacing delays. If traffic.min_delay / traffic.max_delay are set, they add artificial send delay. Remove them or set to 0:
    traffic:
      min_delay: 0
      max_delay: 0
    
  5. DNS resolution. Ensure net.dns points to a fast DNS server:
    net:
      dns: "8.8.8.8:53"
    
Symptom: The tunnel connects and then repeatedly tears down and reconnects every few minutes. Logs show reconnect messages cycling.Cause: The liveness/control stream ping-pong is not completing within the configured timeout, or the session lifetime limit is being hit.Fix:
  1. Check liveness settings. The default values work for most networks. If you are on a high-latency connection, increase the timeout:
    liveness:
      interval: 10s    # how often to send a ping
      timeout: 5s      # how long to wait for a pong
      failures: 3      # how many missed pongs before rebuild
    
  2. Check lifecycle.max_session_duration. If set, this causes a planned rebuild after the given time:
    lifecycle:
      max_session_duration: 6h   # remove or increase if rebuilds are too frequent
    
    Setting this also causes clean session ends to restart automatically so both sides can resync. If you do not need planned rebuilds, remove this field.
  3. Check failover profiles. If profiles: is configured, the supervisor rotates through them on failure. Ensure the profile order and settings match on both server and client.
  4. Enable debug: true to see exactly which liveness check is failing.
Symptom: olcRTC exits with an error when socks.host is set to 0.0.0.0 or a LAN IP.Cause: olcRTC enforces that if socks.host is not a loopback address (127.0.0.1, ::1, or localhost), then socks.user and socks.pass must be set. This prevents accidentally creating an open SOCKS5 proxy accessible from the network or the internet.Fix:Set credentials alongside the non-loopback host:
socks:
  host: "0.0.0.0"
  port: 8808
  user: myuser
  pass: mypassword
Then connect with:
curl --socks5-hostname myuser:mypass@0.0.0.0:8808 https://icanhazip.com
# or
export all_proxy=socks5h://myuser:mypass@0.0.0.0:8808
Symptom: Running two olcRTC client or server instances on the same machine causes them to interfere with each other, or only one works.Cause: Each olcRTC instance needs its own isolated configuration. Sharing a room ID means both instances join the same WebRTC room and may receive each other’s traffic. Sharing a SOCKS5 port means the second bind fails.Fix:Each instance must have:
  1. A unique room ID — different room.id value per instance pair
  2. A unique SOCKS5 port — different socks.port per client instance
  3. Its own YAML config file — pass each config file as a separate argument
Example for two separate tunnels:
# client-a.yaml
mode: cnc
room:
  id: "https://meet.example.org/room-a"
socks:
  port: 8808
# client-b.yaml
mode: cnc
room:
  id: "https://meet.example.org/room-b"
socks:
  port: 8809
Run them separately:
olcrtc client-a.yaml &
olcrtc client-b.yaml &

Enabling Debug Logging

Add debug: true to the top level of your YAML config:
debug: true
mode: cnc
auth:
  provider: jitsi
# ... rest of config
With debug logging enabled, look for:
  • jitsi: joining MUC / jitsi: MUC joined — Jitsi connection progress
  • jitsi: session-initiate received — Jingle negotiation started (peer joined)
  • jitsi: bridge open — colibri-ws channel ready
  • vp8channel: peer confirmed — VP8 transport peer latched
  • livekit reconnect — LiveKit reconnect attempts
  • Liveness ping/pong lines — control stream health

Container / Script-Based Deployments

If you are running olcRTC inside a container or via a shell script, use these commands to inspect the running state:
# List running containers
podman ps

# Follow live logs from a named container
podman logs -f olcrtc-server

# Follow live logs from a client container
podman logs -f olcrtc-client
For scripted setups, add debug: true to the config and redirect logs to a file:
olcrtc server.yaml 2>&1 | tee /var/log/olcrtc-server.log

Build docs developers (and LLMs) love