Troubleshooting Cosmonic Desktop
When something goes wrong in Cosmonic Desktop, your first stop is the Logs view.
Start with the Logs view
The Logs view streams the daemon's event log. Deployment failures land there as Failed events carrying the real underlying error—the reconciler fails fast with the cause rather than retrying silently, so the first Failed line for a workload is usually the answer.
One caveat: check the status bar first. If it doesn't say live, the app isn't connected to its daemon, and what you're looking at may be out of date.
The status bar says "stale" or "disconnected"
The status bar reports the app's connection to its daemon: live (connected), stale (showing the last-known-good real data through a transient blip), or disconnected (no daemon reachable—the app never shows fabricated data). Brief blips resolve themselves; a persistent stale or disconnected state means the daemon isn't running or its socket isn't reachable.
- macOS: the daemon runs as a LaunchAgent. Restart it with
launchctl kickstart -k gui/$(id -u)/com.cosmonic.cosmonicd, or quit and relaunch the app. - Linux: on
.deb/.rpminstalls, checksystemctl --user status cosmonicd.service; on AppImage installs the app configures the same user service on first run. Relaunching the app also verifies and starts the daemon. - Windows: the installer configures the daemon to start at login. If it's stopped, launching the app starts it again.
To check the daemon directly, run cosmonicd paths (see Where everything lives for the binary's location on your platform) and verify the socket exists and the process is alive.
The app is blocked at launch by macOS Gatekeeper or Windows SmartScreen
Releases are code-signed—Developer ID-signed and notarized on macOS, Authenticode-signed on Windows—so the OS should not warn on a healthy download. If Gatekeeper or SmartScreen blocks the app, the download may be corrupted or tampered with. Delete it, re-download from your invitation links, and don't override the OS protections. (Local from-source builds are unsigned and will warn—that's expected for development.)
Image pull fails: "error downloading to inspect" or a 401 / DENIED
Symptom. Pasting an OCI reference or repository URL fails at the inspect step, or the workload fails at pull. The Logs view shows a Failed event starting with pulling <image>: followed by the registry's error.
Cause. The image lives in a private registry or package. GHCR is a common trap: packages default to private even when the source repository is public, and the release workflow that pushes an image doesn't change its visibility. The daemon pulls anonymously unless it finds a credential.
It can also work on one machine and fail on another: for ghcr.io, the daemon falls back to the machine's GitHub CLI credentials as a last resort—a laptop that's run gh auth login can pull a private package; a fresh machine can't.
Fix (any one of these):
- Make the package public—for GHCR: the package's settings page → Danger Zone → Change visibility. The right answer for images a public repository tells people to pull.
- Add a registry credential in Desktop's registry settings on the failing machine.
- Run
gh auth loginon the failing machine (GHCR only).
Workload fails permanently: HostPath volume ... does not exist
Symptom. A workload with a hostPath volume fails immediately with a single Failed event and never restarts. The reconciler classifies this as permanent—a restart can never fix it—so it fails once instead of churning through backoff.
Cause. The runtime never creates hostPath directories. The path must already exist and be writable by the daemon, which runs as your user, not root. Specs written for clusters conventionally use /var/lib/... paths that an unprivileged desktop daemon can't create.
Fix. If the data doesn't need to survive restarts, the simplest fix is switching the volume to ephemeral: {}—no directory required. Otherwise, edit the spec's path to a user-writable location and create it first. The path is used verbatim—it must be absolute (~ and environment variables aren't expanded). A good convention is a volumes/ subdirectory of the daemon's state directory, so workload data lives beside the specs and image cache:
| Platform | Path |
|---|---|
| macOS | /Users/<you>/Library/Application Support/Cosmonic/volumes/<workload> |
| Linux | /home/<you>/.local/share/cosmonic/volumes/<workload> |
| Windows | C:\Users\<you>\AppData\Roaming\Cosmonic\volumes\<workload> |
No tray icon on GNOME
GNOME (including RHEL and stock Fedora) ships without status-tray support—StatusNotifier/AppIndicator icons render only with an extension installed. This affects every tray-bearing app, not just Cosmonic Desktop. Install and enable the AppIndicator extension to see the tray.
Where everything lives
Run cosmonicd paths to print the resolved state directory, socket/pipe, and runtime locations for your platform. The binary ships inside the app:
| Platform | cosmonicd binary |
|---|---|
| macOS | /Applications/Cosmonic Desktop.app/Contents/Resources/cosmonicd |
Linux (.deb/.rpm) | cosmonicd (on PATH via /usr/local/bin) |
| Linux (AppImage) | Bundled inside the AppImage, not on PATH—for CLI use, install the .deb/.rpm instead, or ask us for a standalone daemon binary |
| Windows | %LOCALAPPDATA%\Programs\Cosmonic Desktop\resources\cosmonicd.exe |
Set COSMONIC_STATE_DIR to relocate state entirely.
Still stuck?
Your bug reports shape Cosmonic Desktop—email product.feedback@cosmonic.com with the Failed event text from the Logs view.