Syncthing watcher fails on folder with error while traversing: permission denied, but scan/sync works fine in Docker

I know this issue is related to my own setup, but I’ve already tried debugging it myself and couldn’t find a good explanation. After digging a lot by myself (and AI) I wonder if other people might have a clue.

Hi,

I am running Syncthing in Docker on a UGREEN NAS (UGOS, accessed via SSH as root). The Syncthing image is lscr.io/linuxserver/syncthing:latest. I have setup quite a few syncs on various devices. All work fine except one.

I have this one specific folder that syncs correctly, but the filesystem watcher fails to start for it with:

Filesystem Watcher Errors
Shared - Grand Cocon Douillet: error while traversing /gcd: permission denied

What is confusing is that actual sync seems to work. The only visible consequence is that changes made directly on the NAS side are detected more slowly than usual, which makes me think Syncthing falls back to periodic rescans instead of live watching.

Environment

Relevant compose excerpt:

name: syncthing
services:
  syncthing_ambroise:
    image: lscr.io/linuxserver/syncthing:latest
    container_name: syncthing-ambroise
    hostname: syncthing-ambroise
    restart: unless-stopped
    environment:
      - PUID=1002
      - PGID=100
      - TZ=Europe/Paris
      - UMASK=002
    group_add:
      - "133"
    ports:
      - "8384:8384"
      - "22000:22000/tcp"
      - "22000:22000/udp"
      - "21027:21027/udp"
    volumes:
      - /volume3/docker/syncthing/ambroise/config:/config
      - /volume4/@home/<hide>:/data-ambroise
      - "/volume4/Grand Cocon Douillet:/gcd"

Problematic folder

Folder in Syncthing:

  • Folder ID: Shared - Grand Cocon Douillet

  • Path: /gcd (mapped to /volume4/Grand Cocon Douillet)

Main symptom

Watcher error repeats in logs:

2026-03-09 20:44:43 WRN Failed to start filesystem watcher (wait=2m0s error="error while traversing /gcd: permission denied" folder.id="Shared - Grand Cocon Douillet" folder.type=sendreceive log.pkg=model)
2026-03-09 20:46:43 WRN Failed to start filesystem watcher (wait=4m0s error="error while traversing /gcd: permission denied" folder.id="Shared - Grand Cocon Douillet" folder.type=sendreceive log.pkg=model)
2026-03-09 20:47:32 WRN Failed to start filesystem watcher (wait=1m0s error="error while traversing /gcd: permission denied" folder.id="Shared - Grand Cocon Douillet" folder.type=sendreceive log.pkg=model)
2026-03-09 20:48:32 WRN Failed to start filesystem watcher (wait=2m0s error="error while traversing /gcd: permission denied" folder.id="Shared - Grand Cocon Douillet" folder.type=sendreceive log.pkg=model)
2026-03-09 20:50:32 WRN Failed to start filesystem watcher (wait=4m0s error="error while traversing /gcd: permission denied" folder.id="Shared - Grand Cocon Douillet" folder.type=sendreceive log.pkg=model)

What makes this strange

Inside the container, traversing /gcd works fine, including when using the actual Syncthing runtime user.

Syncthing process user

docker exec syncthing-ambroise ps -o user,pid,comm,args -ax | grep syncthing

Output:

root          38 s6-supervise    s6-supervise svc-syncthing
abc          164 syncthing       syncthing --home=/config --no-browser --no-restart --gui-address=0.0.0.0:8384
abc          197 syncthing       /usr/bin/syncthing --home=/config --no-browser --no-restart --gui-address=0.0.0.0:8384

Container shell default user

docker exec syncthing-ambroise id

Output:

uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video),133

Actual Syncthing app user inside container

docker exec syncthing-ambroise sh -c 'id abc'

Output:

uid=1002(abc) gid=100(abc) groups=100(abc),1000(users)

Traversal tests as root inside container

docker exec syncthing-ambroise sh -c 'ls -ld /gcd'
docker exec syncthing-ambroise sh -c 'find /gcd -type d -print >/dev/null'

Output:

drwxrwxrwx 1 root root 714 Mar  9 20:26 /gcd

find produced no error.

Traversal test as Syncthing user (abc)

docker exec syncthing-ambroise sh -c 's6-setuidgid abc find /gcd -type d -print >/dev/null'
docker exec syncthing-ambroise sh -c 's6-setuidgid abc find /gcd -type d 2>&1 | grep -i denied'

Both completed with no output and no error.

So from inside the container, including as the actual Syncthing user, /gcd appears traversable.

Host-side permission / ACL inspection

On the NAS host:

getfacl -p "/volume4/Grand Cocon Douillet"

Output:

# file: /volume4/Grand Cocon Douillet
# owner: root
# group: root
user::---
group::---
other::---

And:

namei -l "/volume4/Grand Cocon Douillet"

Output:

f: /volume4/Grand Cocon Douillet
drwxr-xr-x root root /
drwxr-xr-x root root volume4
d--------- root root Grand Cocon Douillet

So on the host, that directory looks like mode 000, owned by root:root.

This is odd, because inside the container /gcd appears as traversable and readable enough for find to work as user abc.

Might be realted to how the UGREEN NAS “UGOS” works with its app “Files” used to create the “Shared” folder “Grand Cocon Douillet”. Hard to tell. (and AI says it’s odd, I have no clue if that’s the case really)

Docker mount inspection

docker inspect syncthing-ambroise --format '{{range .Mounts}}{{println .Source "->" .Destination}}{{end}}'

Output:

/volume4 -> /shared
/volume4/<hide> -> /phone
/volume4/Grand Cocon Douillet -> /gcd
/volume3/docker/syncthing/ambroise/config -> /config
/volume4/@home/<hide> -> /data-ambroise

So /gcd is definitely mounted from the expected host path.

Syncthing config inspection

docker exec syncthing-ambroise sh -c 'grep -nE "<folder | path=" /config/config.xml'

Relevant output:

143:    <folder id="GCD - Door recordings" label="GCD - Door recordings" path="/gcd/Door recordings" type="sendreceive" ...>
511:    <folder id="Shared - Grand Cocon Douillet" label="Shared - Grand Cocon Douillet" path="/gcd" type="sendreceive" ...>
678:        <folder id="" label="" path="" type="sendreceive" ...>

At one point there were two Syncthing folders under the same tree:

  • /gcd

  • /gcd/Door recordings

I suspected nested folders might be the cause, but deleting a sync didn’t make the message go away, I tried deleting both and recreate, but same. Didn’t feel related. (although that’s the only case where I have "a “conflict” of paths which is officially not supported/recommended, and the only case with an error, so it might just be related in a way I don’t understand)

Hypotheses considered

1. Basic container permission issue

Initial hypothesis: Syncthing could not traverse /gcd because of wrong UID/GID / chmod.

Why I considered it:

  • watcher says permission denied

  • the host path has very unusual permissions (000)

Why I think this is not the full explanation:

  • traversal works from inside the container

  • traversal also works when explicitly run as abc, the actual Syncthing user

  • find /gcd -type d gives no permission error at all

2. Docker bind mount problem

Hypothesis: wrong source path or broken mount.

Why I discarded it:

  • docker inspect shows the correct mount

  • /gcd is clearly visible inside container

  • sync itself works

3. Nested Syncthing folders

Hypothesis: watcher fails because /gcd and /gcd/Door recordings were both configured.

Why I considered it:

  • this is not recommended in Syncthing

  • config confirmed nested folder definitions

Why I am not fully convinced this explains everything:

  • I had already tried removing the nested folder from syncing previously and it did not fix the watcher error

  • I do not have a clean before/after proof captured in logs, though

Current situation

  • Folder sync works

  • Filesystem watcher for /gcd does not start

  • Changes made on NAS side are detected more slowly than usual

  • This looks like watcher disabled / failed, with fallback to rescans

  • I’m not sure of the actual impact. I guess that means that unless I manually run “Rescan”, it might take up to an hour to identify the changes. Although my single experiment was faster than 1h, a few minutes. (but maybe I got lucky and it was a full rescan)

What I have NOT done yet

I have deliberately not changed permissions, ACLs, .stignore, or config manually beyond prior basic attempts, because I do not want to change things blindly before understanding the root cause.

So at this stage I am looking for:

  • explanation for how watcher can fail with permission denied while find as user abc succeeds

  • whether UGREEN NAS / UGOS could expose bind-mounted directories in a way that behaves differently for Syncthing watcher vs normal traversal

  • whether the host-side 000 permission state is a red herring or actually the root cause

  • whether nested folders could still be involved even if removing the nested folder previously did not appear to help

  • whether there is a known issue with watcher startup on this kind of NAS / Docker environment


Thank you!

I’m wondering if this could be an inotify limits issue: