Jellyfin Remote Access Not Working: Fix Guide

The Problem

Want to stream your Jellyfin library from outside your home network but cannot connect? Remote access failures in Jellyfin usually show up as:

  • Connection timeout when accessing your server’s public URL
  • “Unable to connect to the selected server” in mobile apps
  • WebSocket errors in the browser console (wss://... failed)
  • Playback works locally but buffers or fails remotely
  • HTTPS certificate warnings or mixed content errors
  • Reverse proxy returns 502 Bad Gateway or blank page

These issues fall into five categories: port forwarding, reverse proxy configuration, WebSocket support, BaseURL settings, and SSL/TLS problems.


Quick Diagnosis

Before diving into fixes, isolate which layer is broken:

TestCommandExpectedIf Failing
Jellyfin running locallycurl http://localhost:8096HTML responseContainer is down — check docker logs jellyfin
Port exposed from containerdocker ps | grep jellyfin0.0.0.0:8096->8096Fix port mapping in docker-compose.yml
Reverse proxy reaching Jellyfincurl -I http://jellyfin.example.com200 or 301 redirectCheck reverse proxy config
SSL workingcurl -I https://jellyfin.example.com200 with valid certCheck certificate and HTTPS config
WebSocket connectedBrowser DevTools → Network → WS tabActive connectionSee WebSocket section below

Fix 1: Port Forwarding and Firewall

Jellyfin Default Ports

PortProtocolPurposeRequired for Remote?
8096TCPHTTP web interface and APIYes (if no reverse proxy)
8920TCPHTTPS (disabled by default)No (use reverse proxy instead)
1900UDPDLNA service discoveryNo
7359UDPLocal network discoveryNo

If you are using a reverse proxy (recommended), you only need the reverse proxy’s ports (80/443) forwarded on your router. Jellyfin’s port 8096 stays internal.

If you are not using a reverse proxy, forward port 8096 on your router to your server’s local IP.

Firewall Check

# Check UFW status
sudo ufw status

# If 8096 is not allowed and you need direct access:
sudo ufw allow 8096/tcp

# If using a reverse proxy, allow 80 and 443 instead:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Verify the port is reachable from outside your network using an online port checker or from a different network:

curl -I http://YOUR_PUBLIC_IP:8096

ISP Port Blocking

Some ISPs block common ports. If port 8096 is unreachable despite correct forwarding, try an alternative port:

services:
  jellyfin:
    image: jellyfin/jellyfin:10.11.6
    ports:
      - "8097:8096"    # Use 8097 externally

Then forward port 8097 on your router instead.

Alternative approach: Use Tailscale, Cloudflare Tunnel, or WireGuard to bypass port forwarding entirely. These are more secure than exposing ports directly.


Fix 2: Reverse Proxy Configuration

A reverse proxy handles HTTPS termination and routes traffic to Jellyfin. The most common reverse proxy issues are missing WebSocket support and incorrect proxy headers.

Caddy (Simplest Setup)

jellyfin.example.com {
    reverse_proxy localhost:8096
}

Caddy handles HTTPS certificates, WebSocket upgrades, and HTTP-to-HTTPS redirects automatically. This is the easiest option.

Nginx

Create /etc/nginx/sites-available/jellyfin:

upstream jellyfin {
    server 127.0.0.1:8096;
}

server {
    listen 80;
    server_name jellyfin.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name jellyfin.example.com;

    ssl_certificate /etc/letsencrypt/live/jellyfin.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/jellyfin.example.com/privkey.pem;

    add_header Strict-Transport-Security "max-age=31536000" always;
    client_max_body_size 20G;

    location / {
        proxy_pass http://jellyfin;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_buffering off;
    }

    # WebSocket support — REQUIRED
    location /socket {
        proxy_pass http://jellyfin;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable and test:

sudo ln -s /etc/nginx/sites-available/jellyfin /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Traefik (Docker Labels)

services:
  jellyfin:
    image: jellyfin/jellyfin:10.11.6
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.jellyfin.rule=Host(`jellyfin.example.com`)"
      - "traefik.http.routers.jellyfin.entrypoints=websecure"
      - "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt"
      - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
    networks:
      - traefik

networks:
  traefik:
    external: true

Traefik handles WebSocket upgrades automatically with no extra configuration.

Nginx Proxy Manager

  1. Add Proxy Host → Domain: jellyfin.example.com
  2. Forward to: your-server-ip, Port: 8096
  3. Enable Websockets Support (toggle)
  4. SSL tab → Request a new SSL certificate → Force SSL

Fix 3: WebSocket Errors

Jellyfin requires WebSocket connections for real-time features like playback state synchronization, session monitoring, and live notifications. If WebSockets fail, you will see:

  • WebSocket connection to 'wss://...' failed in browser DevTools console
  • Playback appears to work but remote control and sync features are broken
  • “Unable to connect to the selected server” in mobile/TV apps

Diagnosing WebSocket Issues

Open browser DevTools (F12) → Network tab → filter by “WS”:

  • If no WebSocket connection appears, the reverse proxy is blocking the upgrade
  • If a connection appears but immediately closes, the proxy headers are wrong

The Fix

Every reverse proxy listed above includes WebSocket support. The critical parts:

Nginx requires an explicit /socket location block with:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Caddy and Traefik handle WebSockets automatically.

Nginx Proxy Manager requires the “Websockets Support” toggle enabled.

If you are using Cloudflare as a CDN/proxy in front of your reverse proxy, ensure WebSockets are enabled in the Cloudflare dashboard under Network → WebSockets.


Fix 4: BaseURL Configuration

BaseURL is only needed when running Jellyfin behind a reverse proxy with a path prefix like https://example.com/jellyfin. If you use a subdomain (jellyfin.example.com), skip this section.

Setting BaseURL

  1. Access Jellyfin directly via IP: http://YOUR_SERVER_IP:8096
  2. Dashboard → Networking → Base URL
  3. Enter the path prefix: /jellyfin (leading slash, no trailing slash)
  4. Restart the Jellyfin container:
docker restart jellyfin

Reverse Proxy Config with BaseURL

Caddy with path prefix:

example.com {
    redir /jellyfin /jellyfin/ permanent
    reverse_proxy /jellyfin/* localhost:8096
}

Nginx with path prefix:

location /jellyfin {
    return 301 $scheme://$host/jellyfin/;
}

location /jellyfin/ {
    proxy_pass http://127.0.0.1:8096/jellyfin/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
}

location /jellyfin/socket {
    proxy_pass http://127.0.0.1:8096/jellyfin/socket;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

Client App Configuration

When using a BaseURL, mobile and TV apps must include the full path in the server address:

  • Correct: https://example.com/jellyfin
  • Wrong: https://example.com

Fix 5: Known Proxies

If Jellyfin logs show the wrong client IP (the reverse proxy’s IP instead of the real client), or HTTPS detection is broken:

  1. Dashboard → Networking → Known Proxies
  2. Add your reverse proxy’s IP address:
    • Docker bridge network: typically 172.17.0.1 or 172.18.0.1
    • Local reverse proxy: 127.0.0.1

This tells Jellyfin to trust the X-Forwarded-For and X-Forwarded-Proto headers from your proxy.

Find your Docker bridge IP:

docker network inspect bridge | grep Gateway

Fix 6: SSL Certificate Issues

Self-Signed Certificate Warnings

Jellyfin’s built-in HTTPS (port 8920) uses a self-signed certificate that clients reject. Use a reverse proxy with Let’s Encrypt instead:

  • Caddy generates certificates automatically
  • Nginx + Certbot: sudo certbot --nginx -d jellyfin.example.com
  • Nginx Proxy Manager: Built-in Let’s Encrypt integration

Mixed Content Errors

If the browser blocks some resources as “mixed content”, your reverse proxy is not setting the X-Forwarded-Proto header correctly. Jellyfin thinks it is running on HTTP and generates HTTP URLs for some resources, which the browser blocks on an HTTPS page.

Fix by ensuring your reverse proxy sends:

X-Forwarded-Proto: https

And that Jellyfin’s Known Proxies includes the proxy IP (so it trusts this header).


Prevention

  • Use a subdomain (jellyfin.example.com) instead of a path prefix (example.com/jellyfin) — fewer things can go wrong
  • Use Caddy if you want the simplest reverse proxy setup — it handles TLS and WebSockets automatically
  • Set Known Proxies during initial setup, not after something breaks
  • Test from a different network (mobile data, VPN) instead of assuming local tests prove remote access works
  • Consider Tailscale or Cloudflare Tunnel instead of port forwarding — they eliminate most of these issues entirely

Comments