Date: July 13, 2025
Environment: Linux Mint running Jellyfin server
Background
Environment: Linux Mint running Jellyfin server
Access methods in use:
◦ Local LAN access on port 8096
Symptom:
Remote access via Tailscale VPN and DuckDNS dynamic DNS
◦ Quick Connect (device approval) still worked
◦ Manual login at http://<your-server>:8096 always returned "invalid
username or password"
The Story
I’ve spent countless evenings tinkering with my Jellyfin media server, but nothing prepared me for the eight-hour rabbit hole I fell into today. This morning, I tried to log in to manage my libraries—and got an “invalid username or password” message, even though nothing else had changed. Here’s the story of how I chased phantom users, battled locked-out wizards, and finally exorcised the gremlins from my setup.
The Day It All Broke
I woke up, poured my coffee, and navigated to http://my-server:8096. Instead of the familiar dashboard, I was greeted by the awkward sight of the setup wizard—only rather than resetting it, Jellyfin skipped straight to the login screen. My one and only admin account wouldn’t accept its own credentials.
- Quick Connect on my phone still worked (it approved new sessions just fine), but
- Manual login always spit back “invalid username or password.”
No error messages in the logs, no disk space warnings, no sudden system updates—just a lockout of my sole admin account.
Wild Goose Chases (and FFmpeg)
First, I assumed the password database was corrupted. Boldly, I opened the SQLite file and ran:
`sql
UPDATE Users SET Password='MyPlainPassword' WHERE Username='AdminUser';`
No dice. My login still failed. That’s when I realized—Jellyfin hashes everything.
Next, I dug into the Jellyfin CLI, hoping it could export or reset hashes. It returned only inscrutable IDs, no way to reseed my password.
At my wit’s end, I installed FFmpeg on a hunch from a forum thread suggesting missing media dependencies can cause cascade failures. I rebooted, retried the login—still locked out.
The Breakthrough in the Logs
Frustration mounting, I ran the live log stream:
`bash
journalctl -u jellyfin -f`
During a login attempt, I finally saw it:
> DbUpdateConcurrencyException
> The database operation was expected to affect 1 row(s), but actually affected 0 row(s).
In plain English: Jellyfin tried to update my admin record…but couldn’t find it. Something in the database didn’t match the server’s memory of its own users.
Exorcising the Phantom User
1. Reset the Wizard Flag
My interrupted setup had marked the wizard “completed,” so I forced it back on in /etc/jellyfin/system.xml:
`xml
<IsStartupWizardCompleted>false</IsStartupWizardCompleted>`
Restarted Jellyfin. The wizard reappeared—great—but still refused my admin credentials due to the same concurrency error.
2. Hunt Down the Stub Record
I stopped the service, opened the database, and listed users:
`bash
sudo systemctl stop jellyfin
sqlite3 /var/lib/jellyfin/data/jellyfin.db "SELECT Username FROM Users;"`
I found two entries:
1. My real admin account
2. A ghostly stub user left behind by the half-built wizard
3. Delete the Stub
With one line, I banished the phantom:
`sql
DELETE FROM Users WHERE Username='TempHashUser';`
4. Restart and Triumph
`bash
sudo systemctl start jellyfin`
This time, the setup wizard accepted my admin username and password without complaint. I breezed through library setup, and all my media appeared exactly as before.
Cleaning Up & Lessons Learned
1. Sanitize your config: I double-checked system.xml for leftover <Password> tags or test flags—nothing sensitive remained.
2. Verify integrity:
`bash
sqlite3 /var/lib/jellyfin/data/jellyfin.db "PRAGMA integrity_check;"
→ ok
`
3. Test remote access: Tailscale and DuckDNS login still worked over mobile data.
Key takeaways:
- Quick Connect can mask deeper auth failures.
- A single stub user in the DB can block the entire wizard.
- Jellyfin hashes credentials—don’t try plaintext injection.
- Real-time logs (journalctl -f) are your best friend for hidden errors.
- Always back up both your database and config before major surgery.
Final Thoughts
Eight hours felt like forever, but walking through every twist—wrong turns included—gave me an intimate understanding of Jellyfin’s inner workings. Now, when I grab my popcorn and fire up my Plex-killer server, I do so with total confidence that my admin account is bulletproof.
May this tale save you from sleepless nights and blind password strikes. If your Jellyfin ever locks you out, remember: the ghost in your DB could be the key to getting back in.
Happy streaming! 🎬✨