Skip to content

fix(relay): distinguish transient tenant-bind failures from unmapped hosts (#5030) - #5036

Open
yippietheproducer wants to merge 1 commit into
block:mainfrom
yippietheproducer:pr/5030-bind-status
Open

fix(relay): distinguish transient tenant-bind failures from unmapped hosts (#5030)#5036
yippietheproducer wants to merge 1 commit into
block:mainfrom
yippietheproducer:pr/5030-bind-status

Conversation

@yippietheproducer

Copy link
Copy Markdown

Fixes #5030 (the relay-generated half).

Problem

The WS door and every HTTP bridge endpoint collapsed all tenant-bind
failures to 404 "relay: no community is configured for this host". A DB
hiccup during a reconnect therefore looked identical to a decommissioned
relay, and clients that classify 404 as terminal (buzz-acp:
WebSocket(Http): 404 → terminal) gave up on healthy relays. #5030
measured a 22% reconnect-failure rate on hosted communities with agent
sessions going dark once the 5-attempt budget was exhausted.

Fix

bind_community now maps BindError to a status via
BindError::http_status():

  • UnmappedHost404 (permanent — clients correctly stop retrying)
  • Lookup503 (transient — clients retry 5xx; buzz-acp already
    classifies 429 | 502 | 503 | 504 as transient)

The rejection body stays byte-identical for both variants — never echo
the host, never leak the underlying error — preserving the anti-enumeration
property in the steady state. The only new signal is the status code, and
it is observable solely while the backend lookup is actually failing (the
narrow, documented tradeoff; the alternative made healthy relays
indistinguishable from decommissioned ones to every client).

Applied at every bind site: WS door (router.rs), audio handler, and
the four HTTP bridge endpoints (submit_event, query_events,
count_events, workflow).

Notes

Verification

  • cargo check -p buzz-relay — clean, zero warnings
  • New tenant unit test asserting the status split (404 vs 503) and that
    both variants share an identical, error-free body
  • Full buzz-relay lib suite: 848 passed / 1 failed — the failure
    (api::mesh_demo::demo_join_forwarded_arm_round_trips_echo) is a
    pre-existing timing flake, reproduced on the clean tree without this
    change

@yippietheproducer
yippietheproducer requested a review from a team as a code owner August 6, 2026 10:17
…hosts (block#5030)

The WS door and HTTP bridge collapsed every tenant-bind failure to 404
("relay: no community is configured for this host"). A DB hiccup during a
reconnect therefore looked identical to a decommissioned relay, and clients
that classify 404 as terminal (buzz-acp: `WebSocket(Http): 404 -> terminal`)
gave up on healthy relays. block#5030 measured a 22% reconnect-failure rate on
hosted communities with sessions going dark once the 5-attempt budget was
exhausted.

bind_community now maps BindError to a status: UnmappedHost -> 404 (permanent,
clients stop retrying), Lookup -> 503 (transient, clients retry 5xx). The
rejection BODY stays byte-identical for both variants (never echo the host,
never leak the underlying error), preserving the anti-enumeration property in
the steady state; the only new signal is the status code, observable solely
while the backend lookup is actually failing.

Applies to every bind site: WS door (router.rs), audio handler, and the four
HTTP bridge endpoints. Covered by tenant unit tests asserting the status
split and the identical bodies.

Signed-off-by: mmaciejek <chacinskimaciej@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Relay: reconnects fail ~22% of the time on hosted communities (500 in auth path, 404 on WS upgrade)

1 participant