CachyOS / CachyOS/distribution
[Bug]: KIO worker socket error ("Can not create a socket for launching a KIO worker for protocol 'tags'") in native Dolphin (non-portal) under Niri
- Dominant language
- No language data
- Stars
- 27
- Forks
- 2
- PR merge metrics
- No merged PRs in 30d
Description
### Kernel
7.2.3-1-cachyos
### Desktop Environment / Window Manager
Niri (not Plasma) - native Dolphin, not launched via xdg-desktop-portal-kde
### CPU
Not relevant to this issue.
### GPU / Driver
Not relevant to this issue.
### Description
Opening `tags:/` or `trash:/` in a plain, native Dolphin window (not via xdg-desktop-portal-kde, no Plasma session involved) immediately fails with:
> Unable to create KIO worker.
> Can not create a socket for launching a KIO worker for protocol 'tags'.
This looks related to #372 but is a distinct case: that issue was scoped to portal apps under a full Plasma session (kioworker/kded/systemsettings profiles), and reporters there said "native non-portal KDE apps (Dolphin, Kate) work fine". In my case it's the opposite: Dolphin itself, run directly (no portal involved), fails natively.
**Root cause traced via strace:** KIO's `ConnectionServer::listenForRemote()` creates the worker socket file via the standard atomic-rename pattern: `openat(dir, O_TMPFILE|O_RDWR|O_CLOEXEC)` followed by `linkat(AT_FDCWD, "/proc/self/fd/N", AT_FDCWD, "/dolphin..kioworker.socket", AT_SYMLINK_FOLLOW)`. On this system the `linkat` call consistently fails with `ENOENT`, retried ~15 times with fresh random names each time, then Dolphin gives up:
```
ConnectionServer::listenForRemote failed: "QLocalServer::listen: Name error"
KIO Connection server not listening, could not connect
couldn't create worker: "Can not create a socket for launching a KIO worker for protocol 'tags'."
```
The `dolphin` AppArmor profile audit log shows the corresponding `link` operation as `ALLOWED`, but with `info="Failed name lookup - deleted entry" error=-2` (i.e. ENOENT) right before it - AppArmor's own path-resolution for the `link` LSM hook appears to choke on the anonymous/unlinked `O_TMPFILE` dentry (it has no stable path by design), and this seems to corrupt the underlying syscall's outcome even though the final verdict is ALLOW, not DENY.
**Confirmed by testing all three enforcement modes:**
- `enforce` (default): fails, every time
- `complain` (`aa-complain dolphin`): **fails identically** - this rules out a plain permission denial, since complain mode never blocks anything
- fully unconfined (`aa-disable dolphin`): **works immediately**, both `tags:/` and `trash:/` open normally
Reproducing the exact same `openat(dir, O_TMPFILE|O_RDWR|O_CLOEXEC)` + `linkat(AT_FDCWD, "/proc/self/fd/N", ...)` syscall pair standalone (plain Python script, same target directory, same filename pattern) succeeds every time - so this isn't a kernel/tmpfs limitation in general, only something about how AppArmor mediates it in the context of Dolphin's confined process.
As a side effect, this also explains a second, seemingly unrelated symptom: Dolphin's Trash places-panel icon always showed as "full" regardless of actual trash contents, because the `trash:/` KIO worker could never be created to report the real state either. Fixed at the same time as `tags:/`.
### Steps to Reproduce
1. `pkill -x dolphin` (ensure no running instance)
2. `dolphin tags:/` (fresh process, not delegated via D-Bus to an existing window)
3. Observe the error dialog immediately
### Expected Behavior
`tags:/` and `trash:/` open normally in Dolphin.
### Actual Behavior
Immediate error:
> Unable to create KIO worker.
> Can not create a socket for launching a KIO worker for protocol 'tags'.
Trash icon in the places panel permanently shows as full.
### Logs / Error Messages
strace excerpt (full trace available on request):
```
openat(AT_FDCWD, "/run/user/1000", O_RDWR|O_CLOEXEC|O_TMPFILE, 0600) = 44
linkat(AT_FDCWD, "/proc/self/fd/44", AT_FDCWD, "/run/user/1000/dolphinxPWiOm.83.kioworker.socket", AT_SYMLINK_FOLLOW) = -1 ENOENT (No such file or directory)
[... 14 more identical attempts with fresh random names, all ENOENT ...]
```
journalctl:
```
ConnectionServer::listenForRemote failed: "QLocalServer::listen: Name error"
KIO Connection server not listening, could not connect
couldn't create worker: "Can not create a socket for launching a KIO worker for protocol 'trash'."
couldn't create worker: "Can not create a socket for launching a KIO worker for protocol 'tags'."
```
AppArmor audit (kernel log), same operation:
```
apparmor="ALLOWED" operation="link" class="file" info="Failed name lookup - deleted entry" error=-2 profile="dolphin" name="/run/user/1000/#1094" pid= comm="dolphin" requested_mask="l" denied_mask="l" fsuid=1000 ouid=1000
apparmor="ALLOWED" operation="link" class="file" profile="dolphin" name="/run/user/1000/dolphinbFLNbr.88.kioworker.socket" pid= comm="dolphin" requested_mask="l" denied_mask="l" fsuid=1000 ouid=1000 target="/run/user/1000/#1094"
```
### Additional Context
Package versions:
```
qt6-base 6.11.2-3.1
kio 6.29.0-2.1
kio-extras 26.08.0-1.1
dolphin 26.08.0-5.1
apparmor 4.1.7-1.1
apparmor.d 0.4912.0-1
```
The `dolphin` AppArmor profile already contains what looks like the correct rule for this exact socket pattern:
```
owner @{run}/user/@{uid}/dolphin@{rand6}.@{int}.kioworker.socket rwl -> @{run}/user/@{uid}/#@{int},
```
so this doesn't look like a missing-rule issue like #372 was - the rule is present and matches (audit log confirms ALLOWED), but the underlying syscall still fails, which points more toward an AppArmor/kernel LSM `path_link` hook bug when mediating `O_TMPFILE`-based atomic renames specifically, rather than a simple missing permission in the profile itself.
Happy to provide the full strace log or test further AppArmor tweaks if useful for tracking this down.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the failure with a fresh native Dolphin process opening tags:/ or trash:/, then inspect KIO's ConnectionServer::listenForRemote behavior with strace and the dolphin AppArmor audit entries. Compare enforce, complain, and fully unconfined modes, including the O_TMPFILE/linkat sequence. Done means explaining the confined-process failure and validating a project change or a clearly documented blocker without breaking normal worker-socket creation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux
- Domain
- operating-systems, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100