Why leave Plex in 2026: 36,000 servers exposed
On September 9, 2026, Shadowserver published its findings: over 36,000 Plex servers accessible from the internet had not applied the 1.43.3 update, available since May 19. Two CVEs are at the core of this advisory. CVE-2026-96656 (CVSS 7.2) lets an admin-level attacker write arbitrary files that are executed on startup — concretely, load a malicious plugin that drops a rootkit, with no signature or execute-bit check. CVE-2026-96651 (CWE-22, path traversal) allows any authenticated session to read any file accessible to the Plex system user, including the PlexOnlineToken. Combined, these two flaws cover a full escalation scenario: session theft, then code execution. Plex patched both in build 1.43.3.10861; build 1.43.3.10896 is the recommended target. The structural problem remains: Plex is proprietary software whose patch cycle depends on a single vendor, and 36,000 administrators had not applied a four-month-old fix.
What Plex hides behind its cloud model
Plex offers a polished interface, but its cloud model introduces hidden dependencies that become problematic in the event of a security patch or service discontinuation.
- Remote access via Plex Relay: every stream goes through plex.tv servers, even if your VPS is the only one storing the files. Plex sees your playback metadata.
- Plex Pass required for key features: offline sync, full multi-user access, Live TV, and remote access without port forwarding are reserved for paying subscribers.
- Centralized authentication: your clients' logins go through Plex servers. A plex.tv outage locks you out of your own files.
- Uncontrolled updates: Plex can deploy server-side changes (relay, authentication) without you being able to audit or block them.
- Active telemetry by default: playback, searches, and viewing habits are sent to the vendor unless manually disabled in each client.
Prerequisites before starting the migration
This procedure targets a root VPS running Debian 12 or Ubuntu 22.04 LTS. You need SSH root or sudo access, Docker and Docker Compose installed (v2+), and a media directory accessible for reading. Take a VPS snapshot before starting — snapshots are reversible in one command and cost less than an hour of compute. Jellyfin replaces the video library; Navidrome replaces the music library. Both are open source, subscription-free, and exposed behind an Nginx reverse proxy.
Plex → Jellyfin migration: step-by-step
Here is the complete procedure for migrating your Plex library to Jellyfin without losing your data or watch history.
Create a VPS snapshot
First:
snapshot create plex-before-migrationfrom your provider's panel (or equivalent API). This step is your safety net; do not skip it.Stop Plex cleanly
systemctl stop plexmediaserver systemctl disable plexmediaserverWait for the shutdown confirmation before continuing. Plex must no longer be listening on port 32400.
Install Jellyfin via Docker Compose
# /opt/jellyfin/docker-compose.yml services: jellyfin: image: jellyfin/jellyfin:latest container_name: jellyfin restart: unless-stopped ports: - "8096:8096" volumes: - /opt/jellyfin/config:/config - /opt/jellyfin/cache:/cache - /data/media:/media:ro environment: - JELLYFIN_PublishedServerUrl=https://jellyfin.your-domain.comReplace
/data/mediawith the exact path to your media files. The volume is mounted read-only (:ro) as a precaution.Start Jellyfin and run the setup wizard
cd /opt/jellyfin && docker compose up -dAccess
http://VPS-IP:8096for the web wizard. Create the admin account, then add your libraries pointing to/media/films,/media/series, etc.Scan libraries and verify metadata
Jellyfin uses The Movie Database (TMDB) and TheTVDB by default. The first full scan takes between 5 and 30 minutes depending on library size. Verify that covers, synopses, and ratings display correctly. If a title is not automatically recognized, use the Identify function to force the match.
Configure Jellyfin clients
Official Jellyfin apps are available on Android, iOS, Apple TV, Android TV, Roku, and browsers. They are free and open source. Point each client to your server's internal or public URL — no third-party authentication required.
Verify transcoding and subtitles
In Dashboard > Playback, enable hardware transcoding if your VPS has a GPU (Intel Quick Sync, NVIDIA NVENC). Test an H.265 file from a mobile client to validate that software transcoding works as fallback. Also verify that SRT and ASS/SSA subtitles display correctly.
Remove Plex
apt remove plexmediaserver --purge rm -rf /var/lib/plexmediaserverOnly remove the old installation after validating Jellyfin on at least one client for 48 hours.
Music migration: Plex → Navidrome
Navidrome is an open source music server compatible with the Subsonic API, giving it access to the entire client ecosystem (DSub, Symfonium, Ultrasonic, Airsonic, etc.). It reads ID3 v2.3 and v2.4 tags, FLAC, MP3, AAC, OGG, and Opus files. M3U playlists present in your music directory are imported automatically, provided paths are relative to the music root.
Check folder structure
Navidrome expects an
Artist/Album/Track.mp3hierarchy. If your files are already organized this way (which Plex also requires), no reorganization is needed. Check for special characters in folder names (/,:,?).Migrate Plex playlists
Plex does not natively export playlists in M3U format from the interface. Use the
plexapiPython tool to export:python3 -m plexapi.playlist export --token YOUR_TOKEN --output /data/music/playlists/. The generated M3U files are automatically imported by Navidrome if paths are relative to the/musicvolume.
Plex vs Jellyfin vs Navidrome comparison
The following table compares the essential criteria for choosing between Plex, Jellyfin, and Navidrome.
Scroll the table
| Criterion | Plex | Jellyfin | Navidrome |
|---|---|---|---|
| License | Proprietary (freemium) | GPL-2.0 open source | GPL-3.0 open source |
| Remote access without subscription | No (Plex Pass required) | Yes, native | Yes, native |
| Third-party authentication required | Yes (plex.tv) | No | No |
| Video library | Yes | Yes | No (music only) |
| Music library | Yes (limited) | Partial | Yes (specialized) |
| Hardware transcoding | Plex Pass required | Native (NVENC, QSV, VAAPI) | N/A (audio only) |
| Official mobile clients | Paid on iOS/Android | Free, open source | Third-party Subsonic clients |
| Cloud dependency | Strong (relay, auth) | None | None |
Nginx reverse proxy configuration for Jellyfin
Jellyfin must be exposed via HTTPS. The configuration below assumes a Let's Encrypt certificate managed by Certbot or your CDN in Full (strict) mode. Never expose port 8096 directly — always go through Nginx.
# /etc/nginx/sites-available/jellyfin
server {
listen 80;
server_name jellyfin.your-domain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name jellyfin.your-domain.com;
ssl_certificate /etc/letsencrypt/live/jellyfin.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/jellyfin.your-domain.com/privkey.pem;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
location / {
proxy_pass http://127.0.0.1:8096;
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 3600;
}
}Apply the same structure for Navidrome, replacing the port with 4533. Activate the config with nginx -t && systemctl reload nginx.
Troubleshooting: the 3 most common migration errors
Here are the three most common problems during a Plex/Jellyfin migration, with their direct solutions.
- Library empty after first scan: verify that the Docker-mounted path exactly matches the directory containing your files.
docker exec jellyfin ls /mediashould list your folders. If the volume is empty, fix the mapping in docker-compose.yml and restart the container. - Transcoding fails with ffmpeg error: Jellyfin ships its own version of ffmpeg. If the container has no GPU access, disable hardware transcoding in Dashboard > Playback and switch to software transcoding. On a VPS without a GPU, this is the normal configuration.
- iOS/Android clients cannot find the server: make sure the firewall allows port 443 from outside (
ufw allow 443), your DNS points to the VPS IP, and the TLS certificate is valid. Test withcurl -I https://jellyfin.your-domain.com/healthfrom your local machine.
Keep Plex disabled (not uninstalled) for the first 48 hours after migration. The VPS snapshot lets you roll back in under five minutes. Only delete Plex config files (/var/lib/plexmediaserver) after confirming all your clients work correctly on Jellyfin and Navidrome.
Conclusion
36,000 unpatched Plex servers are not a sign of individual negligence: they reveal a structural dependency on a proprietary vendor whose patch cycle is opaque. CVE-2026-96656 and CVE-2026-96651 show that this dependency has a measurable cost. Jellyfin and Navidrome give you back control: no third-party authentication, no cloud relay, no subscription for remote access. The migration takes under an hour with this guide; the library is intact on arrival. If you host your media on a root VPS, there is no longer any reason to wait.