Repository navigation
omarchy-windows-vm: launch fails silently after the first success (setgid re-chmod loop on ~/Windows) #11575
Copy link
Copy link
Closed
Description
What happened
After the compose file is migrated to the new root-owned location (/var/lib/omarchy/windows/docker-compose.yml), every subsequent omarchy-windows-vm launch/up/up_wait call keeps re-validating and re-chmoding the legacy shared-folder source directory (~/Windows), and that re-validation reliably fails after the first successful launch — with the VM's own critical desktop notification "Failed to start Windows VM" and no diagnostic text printed anywhere (not on the terminal, not in the journal for the launching scope).
Root cause chain, confirmed by tracing with bash -x through pkexec omarchy-windows-vm __priv up_wait:
assert_mounts_safe()unconditionally callsprepare_caller_mounts()on every privileged action whenEUID == 0(i.e. on everyup/up_wait, not just the first-time migration):if ((EUID == 0)); then prepare_caller_mounts || return 1 fiprepare_caller_mounts()re-opens the legacy source directories (~/.windows,~/Windows) and requires their mode to read back as exactly700after doingchmod 0700on them:This branch has nochmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" || { ...; return 1; } storage_mode=$(stat -Lc '%a' ...) shared_mode=$(stat -Lc '%a' ...) if [[ $storage_mode != 700 || $shared_mode != 700 ]]; then ... return 1 fiechoon failure — a silentreturn 1that bubbles all the way up to "Failed to start Windows VM" with zero explanation.- In my case
~/Windowshad (and, more importantly, kept getting) a setgid bit (2700instead of0700) — something tied to the running VM's live shared-folder passthrough (this directory is bind-mounted through to the dockurr/windows container as/sharedfor the whole time the VM runs) keeps re-adding the setgid bit shortly after it's cleared. chmod 0700 <path>(a 3-significant-digit numeric mode) does not clear a pre-existing setgid bit — onlychmod 2700/chmod g-s/symbolic notation does. So the script's own remediationchmod 0700call in step 2 is a silent no-op against a directory that already has setgid set, and the mode check keeps failing.
Net effect
- The first launch after migration succeeds (the source dirs happen to be clean at that moment).
- Every launch after that fails, silently, with only a generic "Failed to start Windows VM" notification — because the always-on re-validation in step 1 keeps re-discovering the setgid bit that something (very likely the VM's own SMB/9p sharing of
/sharedwith the Windows guest) keeps restoring. - There is no way for a user to know why it failed short of
bash -x-tracing the privileged helper — none ofomarchy-windows-vm status,launch, or the desktop notification give any hint.
Expected behavior
prepare_caller_mounts's remediation chmod should actually clear pre-existing special bits (e.g.chmod -- 0700numeric mode doesn't do this — usechmod g-s,u-s,-tor an explicit non-abbreviated form, or just retry withchmod 2700 ... && chmod 0700 ...).- More importantly: re-verifying/re-establishing the legacy-source bind mounts on every single launch (even when the compose is already fully migrated and the container/mounts are already up and healthy) seems unnecessary and is what turns a one-off permission quirk into a permanent failure loop. Consider skipping
prepare_caller_mountswhen the expected protected mounts are already active and healthy (mounts_readyalready exists and is checked separately). - At minimum, any failure branch that can end in "Failed to start Windows VM" should surface the actual reason (even just to the journal) instead of a bare
return 1.
Steps to reproduce
- Have an existing Windows VM installed under the older
~/.config/windows/docker-compose.ymllayout with a~/Windowsshared-folder directory that has (or acquires) a setgid bit. - Upgrade Omarchy to a version that migrates the compose to
/var/lib/omarchy/windows/docker-compose.ymland adds theassert_mounts_safe/prepare_caller_mountsre-validation on every launch. - Launch the Windows VM once — it migrates and starts successfully.
- Launch it again while it's still running — it fails with "Failed to start Windows VM" and no further explanation.
chmod g-s ~/Windowsand launch again — succeeds. Wait a few minutes while the VM keeps running, launch a third time — fails again, andstat -c '%a' ~/Windowsshows2700again.
System details
- Omarchy 4.0.3-1
- Hyprland 0.56.2-2
- Docker 29.7.2 / Docker Compose plugin 5.5.1
- CPU: Intel Xeon E5-1660 v4
- GPU: NVIDIA GeForce GTX 1080 Ti (nvidia driver)
~filesystem: btrfs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
windows-vm: actually clear setgid on the shared/storage source before…
windows-vm: actually clear setgid on the shared/storage source before…
Flogrn commentedon Sep 13, 2026
Bug: omarchy-windows-vm install fails with "Failed to write the Windows VM configuration" — recurs even after chmod 0700, and even after running omarchy-update.
Root cause: prepare_caller_mounts() runs chmod 0700 on the storage/shared mount-source file descriptors, then requires the resulting mode to read back as exactly 700. But GNU chmod with a numeric mode doesn't clear a pre-existing setgid bit — chmod 0700 on a 2700 directory leaves it at 2700, so the strict equality check always fails once setgid gets set on the shared folder (e.g. by a prior container run).
Fix that worked: Manually edited /usr/bin/omarchy-windows-vm, changing the line chmod 0700 -- "/proc/$BASHPID/fd/$storage_fd" "/proc/$BASHPID/fd/$shared_fd" to chmod a-s,u=rwx,go= -- ... instead — explicitly stripping setgid rather than relying on the numeric form. Install and launch worked immediately after.
I tracked this down with Claude (Anthropic's AI assistant) — walked through bash -x tracing the script step by step until we isolated the exact failing chmod/stat check.
bjarneo commentedon Sep 20, 2026
Automated duplication check: this issue looks similar to #9334, which covers the same Windows VM setgid permission check. I keep that one open and close this one to keep the discussion in one place.
If you feel this is the wrong decision, please open the issue again with a note on the difference.
omarchybot commentedon Oct 4, 2026
Update: #12323 has merged into
quattro. The setgid permission rejection is now fixed in both source-directory hardening paths, with an explicit mode diagnostic. This does not claim that runtime share privacy or every desktop failure notification is fixed.Scope checked by GPT-6 in Codex and Codex Medium against the discussion and landed change; review independence is not guaranteed. No tests were rerun for this cleanup.
Omabot on behalf of DHH