−
100%
+
fit
scroll
# The Silent Panic — How Inbound Federation
Came Back *A scroll on a task that died
without a sound, and the maze walked to find
it.* ## The symptom Federation looked dead.
`△ mesh fed verify` showed the firehose
sequence frozen at **1**. Posts made on
Bluesky from a linked account never appeared
on hex.hexcraft.dev. The inbound cursor —
the `bsky-cursor` Thing that remembers how far
the Jetstream subscriber has read — had not
moved in **weeks**. Zero posts ingested. And
the strangest tell of all: the subscriber's
log was utterly silent. Not an error, not a
reconnect, not a heartbeat. Nothing. ## The
maze The truth hid behind four false floors,
each convincing: 1. **"The firehose is
down."** No — *outbound* was merely
un-pushed. The firehose only advances on a
manual `▲ mesh fed push`; nothing
auto-emits. One push and 1034 records flowed,
seq 1 → 2. That was a different door. 2.
**"The subscriber is idle."** No — a running
subscriber forces a reconnect every ten
minutes and logs it. Twelve hours of total
silence meant the task wasn't sleeping. It was
*dead*. 3. **"Wrong account."** No —
`hex.hexcraft.dev` resolved to exactly the
watched DID, and the test post sat plainly on
the repo. 4. **"A bad Jetstream instance."**
Tempting — one of the four relay mirrors
genuinely lagged the post in a spot check. But
the Bluesky AppView had indexed the post in
0.3 seconds, so the network *had* it. The
instance was a red herring. ## The floor
beneath the floors The subscriber is a spawned
task. On its very first connection it asks the
TLS layer to build a client config — and the
TLS layer, rustls, **panicked**: > *Could not
automatically determine the process-level
CryptoProvider from > Rustls crate features.*
Two cryptographic providers — `ring` and
`aws-lc-rs` — were both compiled into the
binary, one pulled by the websocket client,
the other by the web server. With two present
and no tie-breaker, rustls refuses to guess.
It panics. And because the subscriber lives
inside a spawned task, that panic killed *only
the task* — no crash, no log, no trace. The
daemon walked on, whole, with one of its
senses quietly severed. That is why the
silence was so complete: a dead limb makes no
sound. The reqwest-based pollers never
noticed, because reqwest carries its own
provider. Only the websocket subscriber leaned
on the absent process default. ## The fix One
line, at the very top of `main`, before any
connection is dreamt of: > install the `ring`
provider as the process default. A rebuild, a
restart, and the subscriber connected — no
panic — replayed the cursor, and within
seconds the test post landed as a Thing. The
count rose, the cursor began to track the live
edge, and a second post drifted in on its own.
Posting on Bluesky now shows up on
hex.hexcraft.dev. The loop is closed in both
directions. ## The lesson A `tokio::spawn`
task that panics dies alone and quietly. When
a background worker goes silent — no errors,
no heartbeat, just absence — suspect a
panicked task before a broken network. And
when two crypto providers share one binary,
name the one you mean. Ambiguity, to rustls,
is not a default. It is a fault.
△