Snaps fail silently on Ubuntu 26.04

Symptom

A desktop snap does nothing when launched — no window, no error, nothing in the app's own logs. Syslog only shows the scope starting:

systemd[19581]: Started snap.kontena-lens.kontena-lens-c30c21da….scope

Exits with code 1 in ~0.2s. Hit this with kontena-lens (Lens) and Obsidian.

Cause

Ubuntu 26.04 replaced GNU coreutils with uutils (Rust) coreutils as /usr/bin/head.

Many snaps bundle an old (2019) desktop-common.sh launcher that tests directories with:

can_open_file() { head -c0 "$1" &> /dev/null; }
  • GNU head -c0 <dir> → exits 0
  • uutils head -c0 <dir> → exits 1 (error reading '...': Is a directory)

Every XDG directory test now fails, so the script sets needs_xdg_links=true and runs its link-repair loop. In a classic snap $HOME == $REALHOME, so that loop runs rmdir ~/Documents against the real home. It fails, stderr goes to /dev/null, and #!/bin/bash -e kills the launcher before Electron ever starts — hence no app logs.

Fix

Prepend the real GNU head (already present as /usr/bin/gnuhead from the gnu-coreutils package) to PATH for the snap.

# GNU head shim
mkdir -p ~/.local/share/snap-gnu-compat
ln -sfn /usr/bin/gnuhead ~/.local/share/snap-gnu-compat/head

# Wrapper (~/.local/bin precedes /snap/bin in PATH)
cat > ~/.local/bin/kontena-lens <<'EOF'
#!/bin/sh
PATH="$HOME/.local/share/snap-gnu-compat:$PATH"; export PATH
exec /snap/bin/kontena-lens "$@"
EOF
chmod +x ~/.local/bin/kontena-lens

# Desktop icon override
sed 's#^Exec=/snap/bin/kontena-lens#Exec='"$HOME"'/.local/bin/kontena-lens#' \
  /var/lib/snapd/desktop/applications/kontena-lens_kontena-lens.desktop \
  > ~/.local/share/applications/kontena-lens_kontena-lens.desktop

Alternatives

  • AppImage / .deb instead of the snap — what I did for Obsidian, and the least fuss.
  • Make GNU coreutils the system-wide default again rather than per-app wrappers. Fixes every affected snap at once, but more invasive.

Diagnosis tips

The wrapper execs between scripts, so bash -x gets lost. Inherit xtrace through the whole chain via the environment:

snap run --shell <snap> -c 'env SHELLOPTS=xtrace bash "$SNAP/desktop-init.sh" \
  "$SNAP/desktop-common.sh" "$SNAP/desktop-gnome-specific.sh" /bin/true'

SNAPD_DEBUG=1 SNAP_CONFINE_DEBUG=1 confirms whether confinement setup succeeded, i.e. whether the failure is snapd's or the app's.

[!warning] Don't trace the launcher with HOME set to the real home The link loop then runs ln -s $REALHOME/Templates $HOME/Templates with both equal, creating self-referential symlinks for ~/Templates and ~/Public. xdg-user-dirs-update then rewrites ~/.config/user-dirs.dirs to XDG_TEMPLATES_DIR="$HOME/", which resolves to . — so a later run attempts rmdir ~/..