diff options
| -rw-r--r-- | assets/outbox/2026-05-12-protonmail-bridge-orphan-instance-and-dns-race.org | 142 | ||||
| -rwxr-xr-x | scripts/cmail-setup-finish.sh | 54 |
2 files changed, 191 insertions, 5 deletions
diff --git a/assets/outbox/2026-05-12-protonmail-bridge-orphan-instance-and-dns-race.org b/assets/outbox/2026-05-12-protonmail-bridge-orphan-instance-and-dns-race.org new file mode 100644 index 0000000..c336b44 --- /dev/null +++ b/assets/outbox/2026-05-12-protonmail-bridge-orphan-instance-and-dns-race.org @@ -0,0 +1,142 @@ +#+TITLE: Proton Bridge — kill the autostart .desktop, add a DNS wait drop-in +#+DATE: 2026-05-12 + +* Summary + +When Proton Mail Bridge is run as a systemd =--user= service (the setup +done on 2026-05-08), two things still need cleaning up that the installer +should handle: + +1. Remove the XDG autostart entry =~/.config/autostart/Proton Mail Bridge.desktop=. + It double-launches Bridge and produces an "orphan instance" error dialog + on every login. +2. Add a small drop-in to the user service so it waits (bounded) for DNS + before starting, instead of spewing name-resolution errors into the + journal on every boot. + +Neither is fatal — mail flows fine — but both are visible noise that +recurs on each boot. + +* Problem 1 — "An orphan instance of bridge is already running" + +** Symptom + +On login, a popup: "An orphan instance of bridge is already running. +Please terminate it and relaunch the application." Dismissing it with OK +is harmless and Bridge keeps working, but it comes back every boot. + +** Diagnosis + +Two launch mechanisms are both active: + +- =systemctl --user enable protonmail-bridge.service= (set up 2026-05-08) + starts =/usr/bin/protonmail-bridge-core --noninteractive= early in the + boot. It grabs Bridge's lock and binds the IMAP/SMTP loopback ports + (127.0.0.1:1143 / :1025). This is the canonical instance now. +- =~/.config/autostart/Proton Mail Bridge.desktop= (created 2026-01-25, + before the systemd migration) fires =protonmail-bridge --no-window= + when the desktop session loads. It finds the core already running, + can't get the lock, and throws the "orphan instance" dialog. + +So the dialog is the second (GUI-wrapper) launcher complaining about the +first (systemd core). The autostart stub is leftover from the old +"manually launched =--no-window= process" setup and should have been +removed when Bridge became a systemd user service. + +The autostart file's contents were: + +#+begin_example +[Desktop Entry] +Type=Application +Name=Proton Mail Bridge +Exec="protonmail-bridge" "--no-window" +X-GNOME-Autostart-enabled=true +#+end_example + +** Fix applied + +#+begin_src bash +rm ~/.config/autostart/"Proton Mail Bridge.desktop" +#+end_src + +Reversible: it's just an XDG autostart stub. Reinstalling the +=proton-bridge= package or copying =/usr/share/applications/proton-bridge.desktop= +into =~/.config/autostart/= would bring it back. The installer should +make sure this file does *not* exist whenever the systemd user service +is the chosen launch mechanism. + +* Problem 2 — name-resolution errors in the journal on every boot + +** Symptom + +For ~10 seconds right after boot, the bridge journal logs repeated: + +#+begin_example +WARN ... Get "https://mail-api.proton.me/tests/ping": dial tcp: + lookup mail-api.proton.me: Temporary failure in name resolution +ERRO ... Cannot download or verify the version file: ... Temporary + failure in name resolution +WARN ... Ping failed, API is still unreachable +#+end_example + +It clears on its own (DNS comes up, Bridge retries and connects). Same +boot-race class as the Tailscale "can't reach configured DNS" footer. + +** Diagnosis + +The packaged unit (=/usr/lib/systemd/user/protonmail-bridge.service=) +only has =After=network.target=, which says nothing about DNS being +ready. The user-instance systemd manager doesn't carry +=network-online.target= / =nss-lookup.target= the way the system +instance does, so ordering against those isn't available in user scope. +The service therefore starts before the resolver is usable and Bridge's +first API calls all fail until DNS comes up a few seconds later. + +** Fix applied + +A drop-in that runs a bounded DNS-wait before =ExecStart=. The leading +=-= makes the pre-step non-fatal: if DNS is still down after 30 s the +service starts anyway and falls back on Bridge's own API-reachability +retry loop (so an offline boot doesn't hang the unit). + +File: =~/.config/systemd/user/protonmail-bridge.service.d/wait-for-dns.conf= + +#+begin_example +[Service] +ExecStartPre=-/bin/sh -c 'for i in $(seq 1 30); do getent hosts mail-api.proton.me >/dev/null 2>&1 && exit 0; sleep 1; done' +#+end_example + +Then: + +#+begin_src bash +systemctl --user daemon-reload +systemctl --user restart protonmail-bridge.service +#+end_src + +Verified: =ExecStartPre= exits 0, service active, IMAP on 127.0.0.1:1143 +answers with the normal capability banner. + +* What the installer should do + +When it sets up Proton Bridge as a systemd =--user= service: + +1. =systemctl --user enable --now protonmail-bridge.service= (already done + today by the 2026-05-08 work — keep it). +2. Ensure =~/.config/autostart/Proton Mail Bridge.desktop= does *not* + exist (remove it if a Bridge install dropped it there). Otherwise the + "orphan instance" popup recurs every login. +3. Install the =wait-for-dns.conf= drop-in above under + =~/.config/systemd/user/protonmail-bridge.service.d/= and + =daemon-reload=. Optional but it keeps the boot journal clean. + +* Context + +- Bridge version at time of writing: 03.24.02 (=protonmail-bridge-core=). +- Host: ratio. The systemd-user-service setup also applies to any other + machine that runs Bridge headless; the autostart-stub cleanup is the + one that bites on a desktop login session specifically. +- Related earlier note (now folded in): the 2026-05-08 Proton Bridge + + cmail-triage setup that first moved Bridge from a manual =--no-window= + process to the systemd user service. The =pass not initialized= warning + noted there is separate and still benign (Bridge falls back to its own + encrypted state). diff --git a/scripts/cmail-setup-finish.sh b/scripts/cmail-setup-finish.sh index de99101..3e119f6 100755 --- a/scripts/cmail-setup-finish.sh +++ b/scripts/cmail-setup-finish.sh @@ -15,8 +15,13 @@ # 2. Copies Bridge's self-signed cert → ~/.config/protonbridge.pem # 3. Symlinks ~/projects/claude-templates/.ai/scripts/cmail-action.py # → ~/.local/bin/cmail-action -# 4. Enables + starts the protonmail-bridge user service -# 5. Verifies Bridge is listening on 127.0.0.1:1143 / :1025 +# 4. Removes the leftover ~/.config/autostart/Proton Mail Bridge.desktop +# stub (it double-launches Bridge alongside the systemd user service +# and throws an "orphan instance" dialog every login) +# 5. Installs a wait-for-dns drop-in so Bridge doesn't spam +# name-resolution errors during the early-boot DNS race +# 6. Enables + starts the protonmail-bridge user service +# 7. Verifies Bridge is listening on 127.0.0.1:1143 / :1025 set -euo pipefail @@ -61,12 +66,51 @@ mkdir -p "$HOME/.local/bin" ln -sf "$cmail_action_src" "$HOME/.local/bin/cmail-action" ok "linked $HOME/.local/bin/cmail-action → $cmail_action_src" -# 5. Enable + start systemd user service +# 5. Remove leftover XDG autostart stub +# The systemd --user service is the canonical launcher. The autostart .desktop +# starts a second Bridge instance that can't get the lock and pops up an +# "orphan instance" dialog every login. +info "removing orphan autostart launcher (if present)" +autostart_stub="$HOME/.config/autostart/Proton Mail Bridge.desktop" +if [ -f "$autostart_stub" ]; then + rm "$autostart_stub" + ok "removed $autostart_stub" +else + ok "no autostart stub present" +fi + +# 6. Install wait-for-dns drop-in +# User-instance systemd doesn't carry network-online.target / nss-lookup.target, +# so the packaged unit's After=network.target doesn't imply DNS readiness. +# Bridge starts before the resolver is up and its first API calls all fail +# until DNS comes online a few seconds later. The drop-in waits (bounded 30s) +# for resolution before ExecStart. The leading '-' on ExecStartPre makes it +# non-fatal, so an offline boot still starts the unit. +info "installing wait-for-dns drop-in" +dropin_dir="$HOME/.config/systemd/user/protonmail-bridge.service.d" +dropin_file="$dropin_dir/wait-for-dns.conf" +mkdir -p "$dropin_dir" +cat > "$dropin_file" <<'EOF' +[Service] +ExecStartPre=-/bin/sh -c 'for i in $(seq 1 30); do getent hosts mail-api.proton.me >/dev/null 2>&1 && exit 0; sleep 1; done' +EOF +ok "wrote $dropin_file" +systemctl --user daemon-reload +ok "reloaded systemd user units" + +# 7. Enable + start systemd user service info "enabling protonmail-bridge user service" +was_active=0 +systemctl --user is-active --quiet protonmail-bridge.service && was_active=1 systemctl --user enable --now protonmail-bridge -ok "service active" +if [ "$was_active" = "1" ]; then + systemctl --user restart protonmail-bridge + ok "service active (restarted to pick up drop-in)" +else + ok "service active" +fi -# 6. Verify +# 8. Verify info "verifying Bridge is listening" if ss -ltn 2>/dev/null | grep -qE '127\.0\.0\.1:(1143|1025)'; then ok "127.0.0.1:1143 + :1025 LISTEN" |
