ghost register failure is not retried — transient 530 leaves a Discord speaker unbridged until next rejoin #134
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
dark/nether-voicebridge#134
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What happened
Prod, 2026-08-25 05:26:30 UTC ("Discord Bridge" bridge): a Discord speaker rejoined voice ~2s after leaving, and the ghost respawn died on the very first step:
HTTP 530 is a Cloudflare edge error (origin DNS blip) in front of nether.im — a one-shot transient, not a homeserver rejection.
Consequence
In
crates/matrix-rtc/src/rtc/ghost.rs(register_ghostcall at the top of the ghost span, ~line 789), any register failure is fatal for the spawn: log +return. Nothing re-attempts. Recovery only happens on the next presence edge (the Discord user leaving and rejoining voice).Journal evidence of the gap: the user (
803521498823262229) stayed in voice speaking (SSRC mapping logged at 05:26:33) until 05:29:18 — ~3 minutes present on Discord with no Matrix ghost, i.e. invisible and inaudible in the Element Call, with no signal to anyone that a participant was missing.Why register deserves a retry
The later best-effort steps (displayname, avatar) already degrade gracefully, and
join_roomfailure is a meaningful fatal gate (real 403s: room policy). But/registeris idempotent (M_USER_IN_USEcounts as success) and its failures are overwhelmingly transient edge blips — exactly the class that deserves a retry, not a skip.Proposed fix
Retry register (and arguably
join_roomon 5xx-class errors too) with short backoff — e.g. 3–5 attempts over ~30s — while the assignment is still alive; abort only if the user already left (presence re-check after the await, same pattern as the #70 mint-after-leave fix). Keeps "ghost assigned" truthful instead of silently leaking a present-but-unbridged speaker.Low frequency (one occurrence in 11 days of prod logs) but the failure mode is the bad kind: silent partial bridging.