Quick answer

What this guide helps you do

Updating to Jellyfin 12.2? Back up first, update Docker or Ubuntu safely, then fix slow scans, container crashes, out-of-memory kills and transcoding.

Jellyfin beginner path

New to Jellyfin? Follow this order.

These guides form the SmallGrid Jellyfin path: install it, fix folder access, solve empty libraries, reduce unnecessary transcoding, then choose the right mini PC.

  1. How to Reduce Jellyfin Server Power Use on Ubuntu
  2. Give Jellyfin Access to Media Folders on Ubuntu
  3. Jellyfin Library Not Showing Files? 8 Checks That Fix It
  4. Jellyfin Direct Play vs Transcoding: What Is the Difference?
  5. Best Mini PC for Jellyfin: CPU, RAM and Quick Sync Specs

Quick answer

Jellyfin Server 12.2 was released on 5 October 2026. The official release notes describe it as a minor stable release with bug fixes, list no breaking changes or special migration steps, and repeat the standing advice to take a full backup before upgrading.

For most servers the safe routine is:

check version → back up → check plugins → update only Jellyfin → verify → test playback

If something looks wrong afterwards, read the logs before changing anything. Slow scans, container restarts and missing media are more often caused by storage, permissions or memory limits than by a specific release.

At the time of writing, four days after release, I could not find a confirmed Jellyfin 12.2 scanning or crash defect in the official release notes, in the Jellyfin GitHub issues I could find, or in the forum threads I checked. There are individual reports for earlier 12.x versions. Treat those as diagnostic examples, not as proof that 12.2 is affected.


What Jellyfin 12.2 actually changes

Jellyfin 12.2 follows 12.0 and 12.1 on the same 12.x line. It is a bug-fix release, not a feature release.

The official notes list 51 server changes. Changes that matter for a home server include:

  • a fix so the segment cleaner no longer deletes segments ahead of playback when remuxing MKV
  • Dolby Vision profile 8 now uses the hvc1 tag
  • an ATL library upgrade to stop malformed FLAC files hanging a scan
  • numbered sample and trailer files are recognised as extras
  • trickplay generation now checks write permission on the media directory first
  • fixes in database handling, library scanning and a migration performance fix

Read the full list on the Jellyfin Server 12.2 release page before you update. This page summarises it; the release page is the authority.

Jellyfin Web 12.2 also includes a security fix

The Jellyfin Web 12.2 release contains 17 web-client changes, including a security fix for improper escaping of track titles and external URLs.

In practical terms, the web client now escapes those values correctly before rendering them. That reduces the risk of specially crafted metadata or external links being interpreted as active content in the browser instead of being displayed safely as text or URLs.

This is a web-client fix rather than a server migration change, so it does not alter the backup-first upgrade process below. It is still a good reason to keep both the Jellyfin Server and Jellyfin Web components on the current stable release rather than updating only one half of the installation.

Official source: Jellyfin Web 12.2 release notes.

What is confirmed and what is not

StatementStatus
12.2 is a stable bug-fix releaseConfirmed by the official release page
Take a full backup before upgradingOfficial advice on the release page
No breaking changes are listedConfirmed by the official notes
12.2 fixes your specific scan or crash problemNot confirmed. Check the changelog for your symptom
12.2 causes scan or crash problemsNot confirmed. Individual reports are not proof

Do not credit 12.2 with fixes that were shipped in 12.1 or 12.0. If you are still on 12.0, read the Jellyfin 12 upgrade problems guide first, because the 12.0 migration is the larger change.


1. Before you update

Check the installed version and install method

Open:

Dashboard → General

Record the server version, then find out how Jellyfin is installed.

systemctl status jellyfin --no-pager 2>&1 | head -5
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' | grep -i jellyfin
dpkg -l | grep -E '^ii\s+jellyfin'

If the first or third command shows a service or packages, you have a native Ubuntu install. If the second shows a container, you run Docker. Do not change install method during this update. Moving between native and Docker is a separate migration.

Take a backup you can restore

Create a built-in backup under Dashboard → Backups, copy the archive away from the active data directory, and for the final pre-update copy stop Jellyfin and copy the data directories as well. The full procedure is in How to Back Up and Restore Jellyfin Before an Upgrade.

A backup you have not restored is a hope, not a backup. Keep it untouched until the updated server has run normally for a few days.

Check plugins

Open Dashboard → Plugins and list every third-party plugin. Check each plugin’s own page or repository for a build that supports Jellyfin 12.x. If a plugin has no 12.x build, disable it before updating rather than waiting for it to fail. The 12.0 release notes asked users to remove third-party plugin repositories before migrating and to return to the stable repository.

Do not combine changes

Update Jellyfin on its own. Do not combine it with an Ubuntu release upgrade, a Docker Engine update, a storage move or a broad container refresh. If something breaks, you want one change to blame.


2. Updating Jellyfin on Docker

Record what is running

docker inspect jellyfin --format '{{.Config.Image}}'
docker inspect jellyfin --format '{{.Image}}'
docker inspect jellyfin --format '{{range .Mounts}}{{println .Source "->" .Destination}}{{end}}'
docker compose config > compose-effective-before-12-2.yaml
docker compose config --images

Replace jellyfin if your container or service has another name. The rendered Compose file is a record of exactly what you ran. Protect it if it contains secrets.

Write down the image tag, the image ID and every mount. The official image is published as jellyfin/jellyfin on Docker Hub and ghcr.io/jellyfin/jellyfin on GitHub Container Registry. Its tags include latest, X, X.Y and X.Y.Z. If you pin an exact version, check the registry’s tag list for the 12.2 tag instead of guessing the name.

Stop, back up, then update only Jellyfin

docker compose stop jellyfin
docker compose ps jellyfin

Take the final offline copy of the directory mapped to /config, then pull and recreate only that service:

docker compose pull jellyfin
docker compose up -d jellyfin
docker compose ps jellyfin
docker compose logs --timestamps --tail=200 jellyfin

docker compose up -d jellyfin recreates the container from the new image while keeping the volumes and bind mounts defined in your Compose file. Your networking and environment variables also stay as written there, so check the rendered file above if you changed anything outside it.

Avoid a broad docker compose pull, which refreshes every service in the file. Never run docker compose down -v on a media server. The -v flag removes named volumes.

If you started Jellyfin with a plain docker run command instead, keep the exact command you used. A replacement container needs the same volume, port and device options. Moving to Compose is worth doing, but as its own change.

Verify the server

docker exec jellyfin jellyfin --version
docker inspect jellyfin --format 'status={{.State.Status}} exit={{.State.ExitCode}} oom={{.State.OOMKilled}} restarts={{.RestartCount}}'

The version should read 12.2 and the container should be running with zero restarts. Then open the dashboard, not just the login page.


3. Updating Jellyfin on Ubuntu

Confirm which repository and packages you have before upgrading:

apt-cache policy jellyfin jellyfin-server jellyfin-web
grep -RhsE '^(deb |Types:|URIs:|Suites:|Components:|Signed-By:)' \
  /etc/apt/sources.list /etc/apt/sources.list.d 2>/dev/null

The Jellyfin packages should come from the official Jellyfin repository. If you have not set that up, use the official Linux installation instructions, which provide a repository setup script for Debian and Ubuntu. Download it, check the checksum and read it before you run it.

Refresh the package lists and see what is on offer:

sudo apt update
apt list --upgradable 2>/dev/null | grep -i jellyfin

If 12.2 appears, upgrade just the Jellyfin packages:

sudo apt install --only-upgrade jellyfin jellyfin-server jellyfin-web

--only-upgrade upgrades packages that are already installed and does not install new ones. If jellyfin-ffmpeg also appears in the upgradable list, add its exact package name to the command. Do not add -y: read the changes apt proposes before accepting them.

Then confirm the service is healthy:

systemctl status jellyfin --no-pager
sudo journalctl -u jellyfin --since "10 minutes ago" --no-pager
jellyfin --version

If apt list shows no 12.2 package yet, your repository may not have published it for your Ubuntu release. Wait. Do not switch to an unstable repository to get it.


4. Fixing library scanning problems

What normal looks like

Open:

Dashboard → Scheduled Tasks → Scan Media Library

A running scan shows a progress percentage. A first full scan after a major version change such as 12.0 takes noticeably longer than a normal scan. A minor update such as 12.1 to 12.2 should not need a heavy re-scan on its own. If it does, find the reason.

Read the logs first

docker logs --since 30m jellyfin 2>&1 | grep -Ei 'scan|error|denied|permission|timeout|sqlite'

For native Ubuntu:

sudo journalctl -u jellyfin --since "30 minutes ago" --no-pager | \
  grep -Ei 'scan|error|denied|permission|timeout|sqlite'

You can also read the same logs under Dashboard → Logs.

Check mounted storage and permissions

A scan that finds nothing, or keeps repeating, is often a storage problem. From inside the container:

docker exec jellyfin ls -la /media | head
docker exec jellyfin df -h /media /config /cache

On a native install:

ls -la /path/to/your/media | head
df -h /path/to/your/media
sudo -u jellyfin find /path/to/your/media -maxdepth 2 -type f | head -20

Check that:

  • the media path exists and is mounted before Jellyfin starts
  • the path inside the container matches the library path in Jellyfin
  • the Jellyfin user can read the folders and files
  • the cache and config volumes have free space

The 12.2 notes include a change so that trickplay generation checks write permission on the media directory first. If you use trickplay images stored beside your media, make sure that behaviour matches the permissions you intended.

Use Jellyfin Docker Permissions and Jellyfin Docker Volume Paths Explained for the full permission and path checks. If libraries are empty, use Jellyfin Library Not Showing Files. If only new files are missing, use Jellyfin Not Scanning New Files.

Investigate scans that are very long or repeat

Measure before you change anything:

docker stats --no-stream jellyfin

Run it a few times over several minutes. Memory that climbs steadily and never settles is different from a busy but stable scan. Then look for:

  • two libraries that overlap the same folders
  • a network share that is slow or times out
  • files that fail repeatedly in the log
  • a migration still running, which looks like a scan but is not

A GitHub issue (#18086) reports memory growth during “Scan All Libraries” on Jellyfin 12.1 in Docker. That is a useful example of what to look for. It is not evidence that 12.2 behaves the same way.

For deeper analysis use Jellyfin 12 High CPU, Memory and Scan Problems.


5. Troubleshooting Docker crashes

Read the container’s state

docker inspect jellyfin --format 'status={{.State.Status}} exit={{.State.ExitCode}} oom={{.State.OOMKilled}} error={{json .State.Error}} started={{.State.StartedAt}} finished={{.State.FinishedAt}} restarts={{.RestartCount}}'
docker logs --since 30m jellyfin

Exit code 137 means the process received SIGKILL. That does not prove an out-of-memory event, so confirm it.

Check for out-of-memory termination

docker inspect jellyfin --format '{{.State.OOMKilled}}'
sudo journalctl -k --since '-30 minutes' --no-pager | grep -i -E 'oom|out of memory|killed process'

true from the first command, or kernel lines naming the Jellyfin process, mean the container ran out of memory. Also check whether the container has a limit:

docker inspect jellyfin --format '{{.HostConfig.Memory}}'

0 means no container limit. Any other number is a limit in bytes.

Check the host

docker stats --no-stream jellyfin
free -h
df -h

Look at free memory, swap use, CPU load and free disk space on the volumes Jellyfin writes to. A full disk can crash a database-backed service as readily as a lack of memory.

When a restart is not enough

Restarting once is a reasonable first step. Stop restarting and investigate when:

  • the container exits again within minutes
  • OOMKilled is true
  • the logs show repeated database, migration or SQLite errors
  • the disk is full

If the container is stuck in a restart loop, stop it before collecting more evidence:

docker compose stop jellyfin

Do not run docker system prune or delete volumes to “clean up”. Use Docker Container Keeps Restarting? for the general restart-loop workflow.


6. Transcoding and playback

Confirm the settings survived

Open:

Dashboard → Playback → Transcoding

Confirm the expected hardware acceleration method is still selected. For Docker, confirm the GPU device is still mapped:

docker inspect jellyfin --format '{{json .HostConfig.Devices}}'
docker exec jellyfin ls -la /dev/dri 2>/dev/null

On native Ubuntu:

ls -la /dev/dri 2>/dev/null
getent group render video

Read the FFmpeg logs

Transcoding logs appear under Dashboard → Logs, in files named like FFmpeg.Transcode-…. Search them for the error that ended the stream:

docker logs jellyfin 2>&1 | grep -Ei 'ffmpeg|transcod|hardware|vaapi|qsv|nvenc'

The 12.2 notes include a Dolby Vision profile 8 hvc1 change, a low-bitrate quality fix when reducing bit depth and consistent stereo downmix for audio transcodes. If playback of those kinds of file now differs from before, compare it with a plain Direct Play file before assuming something is broken.

Separate transcoding from library and database problems

  • Direct Play works, but a transcode fails: look at hardware acceleration, drivers and FFmpeg logs.
  • Everything plays, but libraries are empty or incomplete: look at storage, permissions and the scan.
  • Nothing works and the server restarts: look at memory, the disk and the database.

Use How to Check Why Jellyfin Is Transcoding and Jellyfin Hardware Transcoding on Ubuntu for the full path.


7. Database migration and recovery

Identify a migration failure

Jellyfin runs database migrations when it starts after an update. Look for failures near the first start:

docker logs jellyfin 2>&1 | grep -Ei 'migration|sqlite|constraint|malformed|duplicate|fatal|error'

On native Ubuntu:

sudo journalctl -u jellyfin -b --no-pager | \
  grep -Ei 'migration|sqlite|constraint|malformed|duplicate|fatal|error'

If the service restarts and retries the same failing step, stop it first:

sudo systemctl stop jellyfin

For Docker Compose:

docker compose stop jellyfin

Preserve the evidence

Before anything else, keep what you have. First check you have the space, then copy the data to a new, dated name. These commands only create copies.

Native Ubuntu:

sudo du -sh /var/lib/jellyfin
df -h /var/lib
sudo cp -a /var/lib/jellyfin /var/lib/jellyfin.failed-$(date +%F)
sudo journalctl -u jellyfin -b --no-pager > ~/jellyfin-failed-$(date +%F).log

Docker (replace the path with your real /config directory):

du -sh /path/to/jellyfin-config
df -h /path/to
cp -a /path/to/jellyfin-config /path/to/jellyfin-config.failed-$(date +%F)
docker logs jellyfin > ~/jellyfin-failed-$(date +%F).log 2>&1

Do not delete rows from the database because a forum post mentions a similar error. Different migration failures have different causes.

Why downgrading the image is unsafe

Pointing your Compose file back at an older image tag does not undo a database migration. The 12.0 release notes strongly recommended a full backup because the database changes mean you cannot roll back without restoring one. Jellyfin 12.2 includes database and migration fixes, so I would not assume an older server can open a database that 12.2 has touched.

The safe rollback unit is the previous Jellyfin version together with the matching pre-update data:

previous Jellyfin version
+
matching pre-update backup

Stop Jellyfin, keep the failed logs, confirm the backup predates the migration, and restore into the matching older version. Follow How to Back Up and Restore Jellyfin Before an Upgrade instead of improvising.

SmallGrid does not have a dedicated Jellyfin database-recovery guide. The closest existing material is the migration and integrity sections of the Jellyfin 12 High CPU, Memory and Scan Problems guide and Jellyfin 12 Upgrade Problems.


Post-update checklist

Do not call the update complete until these pass:

  • Dashboard reports Jellyfin 12.2.
  • The container or service has stayed up with no unexpected restarts.
  • The first start finished without repeating migration or SQLite errors.
  • Libraries show credible item counts and metadata.
  • A newly added test file is detected.
  • One known Direct Play file plays.
  • One required transcode plays, using the expected hardware path.
  • Your main clients connect, and plugins and scheduled tasks run.
  • CPU and memory settle once the update work has finished.
  • The pre-update backup is kept, and you know where it is and how to restore it.

Frequently asked questions

Is Jellyfin 12.2 stable?

The official release page marks it as a stable release, and the notes describe it as a minor release of bug fixes with no breaking changes listed. I found no confirmed 12.2-specific defect four days after release, but that is a short window. Back up, update on a quiet day and check the GitHub issues for your symptom.

Why is Jellyfin scanning everything again?

A heavy scan is expected after a major version change such as 12.0. After a minor update it is not expected, so look for the cause: a library path or mount that changed, media that was unmounted at start-up, a plugin, a metadata refresh you triggered, or a migration still running. Check the logs before you wait it out.

Why does my Jellyfin Docker container restart?

Usually the main process exits and the restart policy starts it again. Common causes are an out-of-memory kill, a full disk, wrong volume paths or permissions, and a failing database migration. Read the exit code and OOMKilled state, then the logs, before recreating anything.

Can I downgrade Jellyfin 12.2?

Not safely by changing the image tag alone, because the database may already have been migrated. Restore the matching pre-update backup into the older version instead.

How can I tell whether Jellyfin ran out of memory?

Run docker inspect jellyfin --format '{{.State.OOMKilled}}' and search the kernel log with sudo journalctl -k --since '-30 minutes' --no-pager | grep -i -E 'oom|out of memory|killed process'. Exit code 137 on its own is not proof.


Official sources

Individual GitHub issues and forum threads are useful examples of specific failures. They do not show that every installation is affected.



Recap

Jellyfin 12.2 is a minor bug-fix release, and the official notes ask for the same thing as every Jellyfin update: take a full backup first.

Work in order:

confirm version and install method
→ take and verify a backup
→ check plugins
→ update only Jellyfin
→ confirm the version and a clean first start
→ test libraries, Direct Play and one transcode
→ read the logs before changing anything else
→ restore the matching backup instead of downgrading the image

If scans, crashes or playback go wrong, find out which layer is failing (storage, memory, transcoding or the database) before you change settings. Keep the pre-update backup until 12.2 has proved stable on your own server.

Jellyfin guide cluster

More Jellyfin fixes and setup guides

These guides link the main Jellyfin setup, permissions, remote access, direct play, and hardware topics together.