Quick answer

What this guide helps you do

Fix Jellyfin permission denied errors on Ubuntu. Test the service user, find blocked parent folders, apply safe ACLs, verify inheritance, and check mounted-drive options.

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. Jellyfin on Ubuntu: Low-Power Setup, Media Folders and Reboot Checks
  2. Jellyfin Library Not Showing Files: Fix Scans, Paths and Permissions
  3. Jellyfin Direct Play vs Transcoding: Differences, CPU Use and How to Check
  4. Best Mini PC Specs for Jellyfin: What Actually Matters

Difficulty

Beginner-friendly

Focus

Jellyfin setup and troubleshooting

Best used for

Practical setup, fixes, and checks

Printable helper

Prefer to work through this step by step?

Download the matching checklist and tick off the common causes while you work through the guide.

Quick answer

For a native Jellyfin installation on Ubuntu, test the real media path as the jellyfin service user:

sudo -u jellyfin find /mnt/media -maxdepth 3 -type f | head -20

Interpret the result before changing anything:

ResultMeaning
Media files are listedLinux access works; check the Jellyfin library path, scan, and logs
Permission deniedJellyfin cannot traverse or read part of the path
Path does not existThe library path or mount point is wrong
Folder is emptyThe disk or network share may not be mounted

For a normal ext4 library, a targeted ACL is usually safer than changing ownership or using chmod 777:

sudo apt install -y acl
sudo setfacl -R -m u:jellyfin:rX /mnt/media
sudo setfacl -R -d -m u:jellyfin:rX /mnt/media
sudo systemctl restart jellyfin

Then repeat the original service-user test.

Use your real media path. Do not copy /mnt/media blindly.


What this guide covers

This guide is specifically for a native Jellyfin package installation on Ubuntu where the Linux jellyfin service account cannot read a media folder.

It covers:

  • confirming the service account
  • testing access as jellyfin
  • identifying the exact parent directory blocking traversal
  • reading Unix modes and ACLs
  • applying the smallest required ACL change
  • setting default ACLs for future files
  • checking ACL masks
  • handling ext4, NTFS, exFAT, SMB, CIFS, and NFS mounts
  • proving that access survives a restart or reboot

It does not cover Docker user IDs or container paths. Use Jellyfin Docker Permissions for container installations.

Use Jellyfin Library Not Showing Files when you have not yet proved that permissions are the failing layer.


Permission model in one minute

Jellyfin needs three different kinds of access:

ObjectRequired accessWhy
Every parent directoryExecute (x)Traverse through the path
Library directoriesRead and execute (r-x)List and enter folders
Media filesRead (r--)Open and stream files

A path can fail even when the final media directory looks readable.

Example:

/home/sean/media/tv

Jellyfin may have access to media and tv but still be blocked by /home/sean.

That is why namei -l is more useful than checking only the final folder.


Diagnostic decision table

EvidenceMost likely causeNext action
id jellyfin failsService account missing or installation incompleteRepair Jellyfin before changing files
Your SSH user can list media but jellyfin cannotUnix mode or ACL blocks the serviceRun namei -l and getfacl
Jellyfin reaches the library root but not one show or filmDeeper folder has different accessInspect that exact path
Existing files work but new imports failNew files inherit unsuitable ownership, mode, or ACLAdd a default ACL and inspect the creating service
ACL entry exists but access still failsACL mask limits the effective permissionCheck mask:: and #effective: output
Permissions appear to reset after rebootMount options define accessInspect findmnt and /etc/fstab
Both your user and Jellyfin see an empty directoryStorage is not mountedFix the mount before changing permissions
Native tests pass but Jellyfin still shows nothingWrong library path, scan, or metadata problemCheck Jellyfin settings and logs

Step 1: Confirm the Jellyfin service account

Check the account:

id jellyfin

A typical result resembles:

uid=112(jellyfin) gid=118(jellyfin) groups=118(jellyfin),44(video),109(render)

The numeric IDs vary by installation. The important point is that the account exists.

Confirm the running service:

systemctl status jellyfin --no-pager

You can also check the configured service user:

systemctl show jellyfin -p User -p Group

Expected shape:

User=jellyfin
Group=jellyfin

If your service uses another account, use that account in every test instead of assuming jellyfin.


Step 2: Confirm the real media path

Find real media files on the host:

ls -ld /mnt/media
find /mnt/media -maxdepth 3 -type f | head -20

A useful result looks like:

/mnt/media/tv/Show Name/Season 01/Show Name - S01E01.mkv

If the command returns nothing, stop. Jellyfin cannot scan files that are not present at the host path.

Linux paths are case-sensitive:

/mnt/media/tv
/mnt/Media/TV

These are different paths.

Check the path configured in Jellyfin under:

Dashboard → Libraries → Select library → Manage folders

For a native installation, the Jellyfin path should normally be the same host path you just tested.


Step 3: Reproduce the failure as Jellyfin

Test progressively deeper paths:

sudo -u jellyfin ls -ld /mnt
sudo -u jellyfin ls -ld /mnt/media
sudo -u jellyfin ls -la /mnt/media
sudo -u jellyfin find /mnt/media -maxdepth 3 -type f | head -20

Test one known file directly:

sudo -u jellyfin stat "/mnt/media/tv/Show Name/Season 01/Show Name - S01E01.mkv"

A confirmed permission failure may look like:

find: ‘/mnt/media/tv’: Permission denied

or:

stat: cannot statx '/mnt/media/tv/Show Name/Season 01/Show Name - S01E01.mkv': Permission denied

Do not rescan Jellyfin yet. First fix the Linux access test.


Step 4: Find the blocking parent directory

Run namei -l against the complete path:

namei -l "/mnt/media/tv/Show Name/Season 01/Show Name - S01E01.mkv"

Sanitised example:

f: /mnt/media/tv/Show Name/Season 01/Show Name - S01E01.mkv
drwxr-xr-x root root     /
drwxr-xr-x root root     mnt
drwx------ sean media    media
drwxr-xr-x sean media    tv
drwxr-xr-x sean media    Show Name
drwxr-xr-x sean media    Season 01
-rw-r----- sean media    Show Name - S01E01.mkv

The blocking point is:

drwx------ sean media media

Only the owner can traverse that directory. Permissions on the deeper tv folder do not help until Jellyfin can pass through /mnt/media.

Inspect the exact blocking folder rather than applying broad changes to the entire filesystem.


Step 5: Inspect ownership, modes, and ACLs

Check standard mode and ownership:

ls -ld /mnt /mnt/media /mnt/media/tv

Check ACLs:

getfacl -p /mnt/media
getfacl -p /mnt/media/tv

A folder with no Jellyfin-specific ACL may look like:

# file: /mnt/media
# owner: sean
# group: media
user::rwx
group::---
other::---

A suitable access ACL includes:

user:jellyfin:r-x

Check the ACL mask

The ACL mask limits named users and groups.

Problem example:

user:jellyfin:r-x                  #effective:---
mask::---

The Jellyfin entry exists, but the mask removes its effective access.

Repair the mask where necessary:

sudo setfacl -m m::r-x /mnt/media

Then inspect the ACL again.


Step 6: Grant access to existing media

Install ACL tools if required:

sudo apt update
sudo apt install -y acl

Grant Jellyfin read access to files and traversal access to directories:

sudo setfacl -R -m u:jellyfin:rX /mnt/media

The capital X applies execute permission to directories and to files that already have an execute bit. This is usually safer than applying lowercase x indiscriminately to every media file.

Verify immediately:

getfacl -p /mnt/media
sudo -u jellyfin find /mnt/media -maxdepth 3 -type f | head -20

Expected ACL shape:

user::rwx
user:jellyfin:r-x
mask::r-x

Jellyfin normally does not need write access to the media library.


Step 7: Make new files inherit access

An access ACL fixes existing objects. A default ACL controls inheritance for new objects created beneath a directory.

Set the default ACL on library directories:

sudo find /mnt/media -type d -exec setfacl -m d:u:jellyfin:rX {} +

For a simpler library root, this may be sufficient:

sudo setfacl -m d:u:jellyfin:rX /mnt/media

Inspect the result:

getfacl -p /mnt/media

Expected default entries include:

default:user:jellyfin:r-x
default:mask::r-x

Create or import a new test directory through the normal workflow, then verify inheritance:

getfacl -p "/mnt/media/tv/New Show"
sudo -u jellyfin find "/mnt/media/tv/New Show" -maxdepth 2 -type f | head

If Sonarr, Radarr, qBittorrent, or another service creates the files, inspect that service’s user, group, and umask. Default ACLs help, but a coherent shared-group design is usually easier to maintain across multiple services.

Use Jellyfin Not Scanning New Files when only newly imported files fail.


Step 8: Restart Jellyfin and verify the scan

Restart the service:

sudo systemctl restart jellyfin

Check its status:

systemctl status jellyfin --no-pager

Repeat the direct access test:

sudo -u jellyfin find /mnt/media -maxdepth 3 -type f | head -20

Read recent logs:

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

Filter likely permission failures:

sudo journalctl -u jellyfin --since "10 minutes ago" --no-pager |
  grep -Ei 'permission|denied|inaccessible|not found'

Then run a manual library scan in Jellyfin.

A successful result requires more than an error-free ACL command. At least one expected media file should appear in Jellyfin after the scan.


Worked before-and-after example

This sanitised example shows the evidence chain for a blocked native Jellyfin service.

Before

Service account:

id jellyfin
uid=112(jellyfin) gid=118(jellyfin) groups=118(jellyfin)

Direct test:

sudo -u jellyfin ls -la /mnt/media/tv
ls: cannot open directory '/mnt/media/tv': Permission denied

Path inspection:

namei -l /mnt/media/tv
drwxr-xr-x root root  /
drwxr-xr-x root root  mnt
drwx------ sean media media
drwxr-xr-x sean media tv

The final tv directory is readable, but /mnt/media blocks traversal.

Change

sudo setfacl -m u:jellyfin:rX /mnt/media
sudo setfacl -R -m u:jellyfin:rX /mnt/media/tv
sudo setfacl -m d:u:jellyfin:rX /mnt/media/tv

After

getfacl -p /mnt/media
user::rwx
user:jellyfin:r-x
mask::r-x

Repeat the original test:

sudo -u jellyfin ls -la /mnt/media/tv

The directory now lists without changing its owner from sean or giving Jellyfin write access.

Final file test:

sudo -u jellyfin find /mnt/media/tv -maxdepth 3 -type f | head -5

The expected media paths are returned.

This before-and-after comparison proves which permission failed and confirms that the targeted change resolved it.


Mounted USB and internal drives

Confirm the storage is mounted:

findmnt /mnt/media
findmnt -no SOURCE,TARGET,FSTYPE,OPTIONS /mnt/media
lsblk -f

ext4

ACLs normally behave as described in this guide.

NTFS and exFAT

Mount options often determine access. Relevant options include:

uid=
gid=
umask=
fmask=
dmask=

Repeated chmod or ACL changes may not persist if the filesystem driver or mount options override them.

Use Jellyfin Cannot Access an External USB Drive for the storage-specific workflow.

Storage disappears after reboot

Validate /etc/fstab before rebooting:

sudo mount -a
findmnt /mnt/media

Use a stable UUID rather than /dev/sdX device names or desktop auto-mount paths.


SMB, CIFS, and NFS shares

Inspect a network mount:

findmnt -no SOURCE,TARGET,FSTYPE,OPTIONS /mnt/media

CIFS access may depend on:

uid=
gid=
file_mode=
dir_mode=

NFS access may depend on server-side exports, UID/GID matching, and root-squash behaviour.

Regardless of the protocol, use the same final test:

sudo -u jellyfin find /mnt/media -maxdepth 3 -type f | head -20

If this fails, Jellyfin cannot scan the share.


Why chmod 777 is not the fix

Avoid:

sudo chmod -R 777 /mnt/media

It gives every local user full read, write, and execute access and can mark ordinary media files executable.

A targeted read-only ACL is safer:

sudo setfacl -R -m u:jellyfin:rX /mnt/media

Jellyfin normally needs to read media, not own or modify it.


Roll back a Jellyfin-specific ACL

Remove only the named Jellyfin access ACL:

sudo setfacl -R -x u:jellyfin /mnt/media

Remove the Jellyfin default ACL from directories:

sudo find /mnt/media -type d -exec setfacl -x d:u:jellyfin {} +

Inspect before and after rollback:

getfacl -p /mnt/media

Do not use setfacl -b casually. It removes all extended ACL entries, including entries that may belong to other services or users.


Exact verification sequence

Run this after the change:

id jellyfin
systemctl show jellyfin -p User -p Group
namei -l /mnt/media
getfacl -p /mnt/media
sudo -u jellyfin ls -la /mnt/media
sudo -u jellyfin find /mnt/media -maxdepth 3 -type f | head -20
findmnt /mnt/media
systemctl status jellyfin --no-pager
sudo journalctl -u jellyfin --since "10 minutes ago" --no-pager

Then confirm in Jellyfin:

  1. The library uses the exact native Linux path.
  2. A manual scan completes without permission errors.
  3. Existing media appears.
  4. A newly created or imported item inherits access and appears.
  5. The same access remains after a service restart.
  6. Mounted storage remains accessible after a controlled reboot.


Recap

Prove the failure with a direct service-user test:

sudo -u jellyfin find /mnt/media -maxdepth 3 -type f | head -20

Find the blocking parent with:

namei -l /mnt/media

For a normal ext4 media library, grant targeted rX access, set a default ACL for future files, check the ACL mask, and repeat the exact original test.

If the media is on NTFS, exFAT, SMB, CIFS, or NFS, inspect mount options because they may control access more than normal Linux ownership and ACLs.

Downloadable checklist

Save the matching PDF checklist

Use these while working through the guide, or keep a copy for the next time the same problem appears.

More downloads are available in the SmallGrid checklists section.

Next guide

What to read next

Continue the setup path with these closely related guides.

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.