u/iChenchus

[BUG] PSA: logrotate silently failing daily on UGOS Pro 1.16.0.0089 — UGOS service logs never rotate (root cause + fix)

Follow-up to my previous post about UGOS silently zeroing POSIX permissions. Different bug, same pattern: the firmware breaks something quietly and nothing surfaces in the UI.

TL;DR: UGOS Pro 1.16.0.0089 (config files in /etc/logrotate.d/ are timestamped June 4, matching that update's install date on my unit) update ships two logrotate config files that claim the same three log files. logrotate refuses to process the conflicting config and exits with an error — every single day — so several UGOS service logs never rotate and just keep growing. Mine reached ~280MB in a month. Check yours.

How to check if you're affected (2 commands over SSH):

systemctl status logrotate.service
sudo journalctl -u logrotate.service --no-pager | tail -10

If you see Active: failed and errors like:

error: ugos_serv:1 duplicate log entry for /var/ugreen/log/conf_tool.slog
error: ugos_serv:1 duplicate log entry for /var/ugreen/log/ug-reporter.slog
error: ugos_serv:1 duplicate log entry for /var/ugreen/log/ugcert-generator.slog
error: found error in file ugos_serv, skipping

…you have it too.

Root cause: /etc/logrotate.d/ctl_serv and /etc/logrotate.d/ugos_serv both declare conf_tool.slog, ug-reporter.slog and ugcert-generator.slog. Both files are timestamped one minute apart from the same firmware package — UGREEN added the three logs to ctl_serv without removing them from ugos_serv. logrotate processes configs alphabetically, ctl_serv wins, and when it reaches ugos_serv it errors out and skips that file entirely — so even the legitimate ugos_serv.slog entry stops rotating, and the whole service exits 1.

Check log directory size: sudo du -sh /var/ugreen/log

Fix (removes the duplicated lines, keeps the legitimate one):

sudo cp /etc/logrotate.d/ugos_serv /root/ugos_serv.logrotate.bak
sudo sed -i '\#conf_tool.slog#d; \#ug-reporter.slog#d; \#ugcert-generator.slog#d' /etc/logrotate.d/ugos_serv
sudo systemctl start logrotate.service && systemctl status logrotate.service --no-pager

Expected result: status=0/SUCCESS and a batch of fresh .slog.1 files in /var/ugreen/log as the backlog finally rotates.

Caveat: the next firmware update may well reinstate the duplicate (same as the permissions bug keeps coming back). I've added sudo logrotate -d /etc/logrotate.conf 2>&1 | grep -i error to my post-update checklist, right next to re-checking shared folder permissions.

Question for the community: can anyone confirm this on their unit? Two data points especially useful: (1) same firmware 1.16.0.0089 on other models — is it DXP4800 Pro-specific or fleet-wide? (2) anyone already on a newer firmware — is the duplicate still there, or did UGREEN silently fix it? Run the two check commands above and report firmware + model. If it's widespread I'll open a ticket with UGREEN engineering referencing this thread.

reddit.com
u/iChenchus — 15 hours ago

[BUG REPORT + diagnosis] UGOS Pro 1.16.0.0089 silently zeroed POSIX permissions on my shared-folder roots — Docker breaks, the GUI shows you a comforting lie, recovery is a forensic exercise

Scope disclaimer up front: this is my experience on one machine (DXP4800 Pro) plus at least one corroborating report from another user on the same model. I am not claiming this is universal across all models/configs. I'm posting the full reproducible diagnosis so others can check whether they're affected and so we can establish how widespread it actually is. If your sudo getfacl comes back clean, great — please say so, that's useful data too.

TL;DR

After updating to UGOS Pro 1.16.0.0089 (I updated 2026-06-04; release was 06-01), the POSIX permission bits on every shared-folder root under /volume2/ were reset to 0000 (--- for owner/group/other). The UGOS GUI keeps displaying your configured permissions as if nothing happened. Docker containers that mount these folders break — but inconsistently, depending on how each container runs. The shared-folder permission editor in the GUI becomes partially unusable (the system "Administrator" group row is greyed out and unmodifiable). The installer log shows no explicit command touching /volume2, so this looks like a side effect of the ugacl driver changing versions rather than an intentional script step. I recovered by reverse-engineering UGREEN's proprietary system.ugacl_self xattr and restoring it from a clean template folder.

Setup

  • Hardware: UGREEN DXP4800 Pro, Intel N100, 32 GB DDR5
  • OS before / after: UGOS Pro 1.15.x → 1.16.0.0089 (1 June 2026)
  • Workload: 14 Docker containers (Navidrome, Immich, Vaultwarden, AudioMuse-AI, Aria2, Syncthing, Cloudflare Tunnel, …)
  • Affected shared folders: all under /volume2/ (in my case: Musica, Downloads, Fotos, BackUP, Cajon, Retales)
  • Filesystem mount (note the proprietary ugacl option):/dev/mapper/ug_..._pool2-volume1 on /volume2 type btrfs (rw,relatime,ugacl,space_cache=v2,subvolid=5,subvol=/)

Symptoms, in the order I hit them

  1. Navidrome (Docker, runs as bare user: "1005:100") — library went blank right after the post-update reboot. DB metadata/art still showed (cached), but playback failed. ls /music inside the container returned Permission denied.
  2. Aria2 (Docker, drops to UID 1004 internally) — couldn't write a new torrent to /volume2/Downloads. Reading existing files was fine; the failure was specifically creating files in the root.
  3. Immich, Vaultwarden (Docker, run as root inside the container) — kept working normally. (Explanation below — it's CAP_DAC_OVERRIDE, and I verified it empirically rather than just asserting it.)
  4. SMB — affected folders vanished from the share list for non-admin users.
  5. GUI — Properties → Permissions showed everything as configured. Hitting "Confirm" did nothing observable to the filesystem.

The core finding: POSIX is zeroed, but the GUI reads a different permission store

ls -ld shows a reassuring lie:

$ ls -ld /volume2/Musica
drwxrwxrwx+ 1 Music_Agent users 60580 Jun 4 13:29 /volume2/Musica

getfacl as a normal user continues the lie:

$ getfacl /volume2/Musica
user::rwx
group::rwx
other::rwx

getfacl with sudo shows the truth:

$ sudo getfacl /volume2/Musica
user::---
group::---
other::---

And the container — which does direct VFS syscalls — agrees with the sudo view:

$ docker exec navidrome ls -ld /music
d--------- 1 1005 users 60580 Jun 4 11:29 /music

This is reproducible on every affected folder. The POSIX bits are genuinely 0000**.**

Why the two views disagree

UGOS mounts /volume2 with a proprietary ugacl option and stores a parallel permission system in Btrfs extended attributes:

$ sudo getfattr -d -m - /volume2/Cajon   # a folder that was NOT broken
system.ugacl_self=0sAQAAAAUAAADPNwAA...   # opaque binary blob, UGREEN format
ug.archive_bit=0sAAMAAA==
ug.archive_version=0sUiUBAAEAAAA=
user.acl.v="1"
user.allow_only_admin_recycle.status="false"
...

system.ugacl_self is what UGREEN's GUI, the File Manager app, and Samba (via UGREEN's VFS module) consult. POSIX bits are what the Linux kernel enforces for direct open()/stat() syscalls — i.e. what Docker containers hit. These two stores can disagree about whether you have access, which is the heart of the problem.

What the update did — observable facts, and what the installer log actually shows

Observable on the filesystem:

  • Every root of /volume2/<shared_folder> had its POSIX bits set to 0000.
  • Subdirectories beneath the root were NOT recursively affected — their bits were untouched. Verified: sudo getfacl /volume2/Fotos/Fondos still showed rwxrwx--- while the root /volume2/Fotos was ---.
  • The system.ugacl_self xattr stayed intact on roots I hadn't touched, which is why admin SMB access and the GUI still "worked".

Timestamp evidence ties it to the update, not to older damage**.** I updated on 2026-06-04 (I deliberately waited 3 days after the 06-01 release to watch for a "chorus of tears"). The ctime of shared folders that have no Docker containers touching them (BackUP, Retales) lands squarely on 2026-06-04 evening, while their mtime (content) stays in March/May:

$ sudo stat /volume2/BackUP | grep -E "Modify|Change"
Modify: 2026-03-27 00:50:50  +0100
Change: 2026-06-04 20:37:00  +0200   ← metadata/permissions changed on update day

$ sudo stat /volume2/Retales | grep -E "Modify|Change"
Modify: 2026-05-23 01:58:58  +0200
Change: 2026-06-04 20:08:50  +0200

Content untouched, permissions rewritten on update day. That rules out "this is leftover damage from a previous incident" — it's this update.

But here's the important nuance: the installer did NOT do it with an explicit command. I pulled the updater log (/var/log/ugpt.log). The only permission operations it performed were system-hardening on OS files, nothing on /volume2:

chmod 4755 /usr/bin/sudo /usr/bin/passwd
chmod 0600 /etc/shadow
usermod --password '*' root

A targeted grep of the entire updater log for anything touching shared folders or the ACL layer came back empty:

$ sudo grep -iE "volume2|ugacl|setfacl|chmod.*volume|reclaim|btrfs" /var/log/ugpt.log
(no output)

So the POSIX zeroing on shared-folder roots is not an explicit step in the install script. The most consistent explanation with all the evidence is that it's a side effect of the ugacl subsystem changing version — i.e. when /volume2 is re-mounted under the new driver after reboot, the new driver's handling of pre-existing shared-folder blobs leaves the kernel exposing POSIX 0000 on the roots. This fits the "roots only, not recursive" pattern: only the shared-folder roots carry the blob the driver re-evaluates; subdirectories don't.

I want to be precise about this because it matters: I cannot point to a line of code that does the damage. I can show (a) it happened on update day, (b) the installer log has no command that would cause it, (c) it only hits the folders that carry the proprietary blob. That points at the driver/migration behavior rather than an intentional script — which, if correct, means UGREEN may not even be aware it's happening.

This also explains the inconsistent container behavior — see next section.

Why each container reacted differently (and an assumption I checked instead of assuming)

Container How it runs Result
Navidrome bare UID 1005, no /etc/passwd entry for it broke instantly
Aria2 entrypoint root → drops to UID 1004 broke on writing to root
Immich / Vaultwarden root inside container unaffected
Postgres / Redis (Immich & AudioMuse) drop to internal postgres/redis users unaffected (data dirs are under /volume1/docker, not shared folders)

The interesting case is the root-inside-container ones. The obvious explanation is "root bypasses POSIX via CAP_DAC_OVERRIDE". A reviewer pushed back that even root needs the execute (x) bit to traverse a directory, which is true on a traditional Unix box — so a 0000 root should block even root from descending.

So I tested it rather than hand-waving. Immich's library subdirectories are d---------:

$ docker exec immich_server ls -la /usr/src/app/upload/library
drwxrwx--- 1 node uucp  96 ... .
d--------- 1 root root  40 ... 8b555369-0c6e-4159-...
d--------- 1 root root 120 ... Xergi

…and yet root inside the container descends into them just fine:

$ docker exec immich_server ls /usr/src/app/upload/library/Xergi
2008
2011
2012

So on this system, CAP_DAC_OVERRIDE (which Docker grants to containers by default) does bypass the directory-traversal check, not just read/write. That's consistent with the Linux capabilities man page ("bypass file read, write, and execute permission checks"). The traditional-Unix intuition doesn't apply to a default Docker container. Confirmed, not assumed.

Recovery, in order of safety

Option A — Fix POSIX from inside a container that can already write

Restores Docker functionality. Caveat: doing a chmod from inside a container destroys the system.ugacl_self xattr on the touched path, so SMB visibility for non-admin users drops afterward. (Found this out the hard way — see the SMB note below.)

docker exec <writable-container> find /<mount> -type d -exec chmod 755 {} \;
docker exec <writable-container> find /<mount> -type f -exec chmod 644 {} \;

Hypothesis, not traced: empirically the blob vanishes after an in-container chmod. My guess is the ugacl driver treats any direct POSIX mutation that doesn't go through its own API as an invalidation event and drops the proprietary blob — but I have not instrumented this, so treat it as inference.

Option B — Recreate / re-edit the share from Panel → Shared Folder

Editing the share from the Shared Folder section of the control panel (not the File Manager "Properties" dialog) regenerated a clean ugacl blob for me. Data on disk is preserved. Stop dependent containers first.

Option C (what finally worked cleanly) — Clone ugacl from a healthy template folder

Create a template shared folder with exactly the permission scheme you want, then copy its xattrs onto the broken folder:

sudo getfattr -d -m ".*" /volume2/Plantilla \
  | sed 's|volume2/Plantilla|/volume2/Musica|g' \
  | sudo setfattr --restore=-

After this, the GUI showed all permissions correctly — including the system "Administrator" group entry that had been stuck greyed-out at "Deny access" with no way to fix it through the UI.

Precaution: do this with all dependent containers stopped, including anything serving SMB if you can. Restoring xattrs on a live folder while a container is mid-write is asking for a metadata race; I don't have evidence of Btrfs locking up from it, but there's no reason to find out the hard way.

Things I could NOT prove (epistemic honesty)

I want this report to survive scrutiny, so here's what is hypothesis, not established fact:

  1. The getfacl**-without-sudo paradox.** A normal user seeing rwx while sudo sees --- is genuinely odd — normally an unprivileged getfacl either reads the real ACL or fails with Permission denied; it shouldn't fabricate rwx. This suggests UGREEN's ugacl layer is returning different answers depending on the calling UID. I could not verify the mechanism because strace is not present on UGOS and I didn't want to start installing tooling mid-incident. If someone has strace working on UGOS and can diff the syscalls for getfacl vs sudo getfacl, I'd love to see it. Until then I'm reporting the behavior, not claiming to understand the cause.
  2. The corrupted blob entry. Decoding system.ugacl_self as 16-byte records (leading type byte 05/06/0A + embedded UID/GID), my broken Musica blob had an entry where a healthy folder carries 0A … 0A 00 00 00 (which I read as "group admin, GID 10"), but mine showed 0x360A (= 13834). getent group 13834, getent passwd 13834, and grep :13834: /etc/{group,passwd} all came back empty, and there are no 5-digit GIDs on this system except nogroup. So 13834 is not a known POSIX id here. BUT — this only rules out a standard POSIX account. If UGREEN maintains a separate internal id map outside /etc/, 13834 could in principle be a legitimate virtual-group id and the real bug would be a migration script that failed to translate old ids. I lean toward "anomalous value" but I can't close this out definitively. This is reverse engineering of an undocumented proprietary format; treat my byte-level reading as a working theory.

Confirmed-by-others (so far)

  • A user on the German UGREEN community (DXP4800 Pro, same model) reported the same Docker-permission breakage after this update — Redis/Paperless couldn't write to its volume, fixed by manually resetting permissions. They didn't dig into the ugacl mechanism.
  • The main 1.16.0.0089 changelog thread has scattered reports but most users said their update was clean — which is exactly why I'm flagging the scope: this is not hitting everyone.

SMB note worth highlighting

After fixing POSIX, non-admin SMB users lost visibility of the folder while admin still saw it. That confirms UGREEN's Samba VFS reads system.ugacl_self and effectively ignores host POSIX. So the two enforcement paths (kernel VFS for Docker vs UGREEN VFS for SMB) are fully decoupled. That decoupling is the root design issue, not any single broken folder.

The opinionated part

Two destructive permission incidents in two months on this box:

  • May 2026: using the GUI's "apply to subfolders" recursively flattened POSIX to 0000, which took down ~19,800 Syncthing items.
  • June 2026 (this update): simply installing the update zeroed POSIX on shared-folder roots.

Maintaining two permission systems that can silently diverge is a known anti-pattern. Synology converged on a coherent ACL model years ago. UGREEN's ugacl tries to do something similar but the sync between it and POSIX is fragile and breaks on updates with no warning. For SMB-only users this may never surface. For anyone running containers as non-root UIDs (a recommended hardening practice), it's a recurring landmine.

Questions for the community

  1. Reproducibility: On any DXP model after 1.16.0.0089, run sudo getfacl /volume2/<your_share>. Do you see ---? Please report model + result (clean results are useful too — I want to know the real blast radius).
  2. Fix status: 1.16.1.0018 dropped 2026-06-04 but apparently only for the iDX series. Anything in the pipeline for DXP models?
  3. ugacl format: has anyone properly reverse-engineered system.ugacl_self? I have before/after hexdumps.
  4. strace on UGOS: anyone got it running? I'd like the syscall diff for the getfacl UID paradox above.

Congratulations to anyone who read this far. There's a sweet waiting at the end of the page — sadly only in spirit.

u/iChenchus — 30 days ago