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:
| Test | Command | Expected | If Failing |
|---|---|---|---|
| Jellyfin running locally | curl http://localhost:8096 | HTML response | Container is down — check docker logs jellyfin |
| Port exposed from container | docker ps | grep jellyfin | 0.0.0.0:8096->8096 | Fix port mapping in docker-compose.yml |
| Reverse proxy reaching Jellyfin | curl -I http://jellyfin.example.com | 200 or 301 redirect | Check reverse proxy config |
| SSL working | curl -I https://jellyfin.example.com | 200 with valid cert | Check certificate and HTTPS config |
| WebSocket connected | Browser DevTools → Network → WS tab | Active connection | See WebSocket section below |
Fix 1: Port Forwarding and Firewall
Jellyfin Default Ports
| Port | Protocol | Purpose | Required for Remote? |
|---|---|---|---|
| 8096 | TCP | HTTP web interface and API | Yes (if no reverse proxy) |
| 8920 | TCP | HTTPS (disabled by default) | No (use reverse proxy instead) |
| 1900 | UDP | DLNA service discovery | No |
| 7359 | UDP | Local network discovery | No |
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
- Add Proxy Host → Domain:
jellyfin.example.com - Forward to:
your-server-ip, Port:8096 - Enable Websockets Support (toggle)
- 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://...' failedin 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
- Access Jellyfin directly via IP:
http://YOUR_SERVER_IP:8096 - Dashboard → Networking → Base URL
- Enter the path prefix:
/jellyfin(leading slash, no trailing slash) - 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:
- Dashboard → Networking → Known Proxies
- Add your reverse proxy’s IP address:
- Docker bridge network: typically
172.17.0.1or172.18.0.1 - Local reverse proxy:
127.0.0.1
- Docker bridge network: typically
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
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments