block/buzz · critical
push HTTP client
Error message
push HTTP client
What it means
run_delivery_worker builds one reqwest::Client (with push_gateway_timeout) for all push-gateway deliveries. Client::build() almost never fails; the realistic failure is TLS-backend initialization (e.g. native-tls/OpenSSL context creation) failing in the process environment. The expect panics, so the push delivery worker task dies at startup and no pushes are ever delivered.
Source
Thrown at crates/buzz-relay/src/push_runtime.rs:316
return true;
}
let p = nostr::SingleLetterTag::lowercase(nostr::Alphabet::P);
filter.generic_tags.get(&p).is_some_and(|values| {
!values.is_empty()
&& values.iter().all(|value| value == lease_author_hex)
&& event
.tags
.filter(nostr::TagKind::SingleLetter(p))
.any(|tag| tag.content() == Some(lease_author_hex))
})
}
/// Continuously claim due wakes and deliver them through the push gateway.
pub async fn run_delivery_worker(state: Arc<AppState>) {
let http = reqwest::Client::builder()
.timeout(state.config.push_gateway_timeout)
.build()
.expect("push HTTP client");
let mut idle_delay = Duration::from_millis(500);
loop {
let mut found = false;
match state.db.usage_community_hosts().await {
Ok(communities) => {
for community in communities {
let community = buzz_core::CommunityId::from_uuid(community.id);
let until = Utc::now() + TimeDelta::seconds(CLAIM_SECS);
match state.db.claim_due_push_wakes(community, 16, until).await {
Ok(wakes) => {
for wake in wakes {
found = true;
deliver_one(&state, &http, wake).await;
}
}
Err(e) => warn!(%community, "push wake claim failed: {e}"),
}
}View on GitHub (pinned to 934f3325c3)
Solutions
- Build reqwest with the rustls TLS backend (features = ["rustls-tls"]) so no system OpenSSL is needed — consistent with the ring provider the relay already installs
- Verify the TLS libraries the binary links (ldd) exist and match inside the runtime image
- Propagate the build error instead of expect so a dead push worker surfaces as an observable startup failure
Example fix
// before
let http = reqwest::Client::builder()
.timeout(state.config.push_gateway_timeout)
.build()
.expect("push HTTP client");
// after
let http = reqwest::Client::builder()
.timeout(state.config.push_gateway_timeout)
.build()
.map_err(|e| {
tracing::error!("push worker: HTTP client build failed: {e}");
e
})?; // make run_delivery_worker return Result and report at spawn site Defensive patterns
Strategy: validation
Validate before calling
// startup preflight before spawning the push worker
let probe = reqwest::Client::builder().build();
if probe.is_err() {
return Err(anyhow!("push worker: reqwest client cannot initialize (TLS backend problem)"));
} Prevention
- Build reqwest with the rustls TLS backend so client construction has no system-OpenSSL dependency
- Include CA certificates and required TLS libraries in minimal runtime images
- Make long-lived worker tasks report init failures observably (metric/log line) instead of panicking silently in the dark
When it happens
Trigger: reqwest compiled with native-tls on a host where OpenSSL fails to initialize (missing or incompatible shared libraries); minimal container images lacking the TLS backend's runtime prerequisites.
Common situations: Distroless/alpine images without a compatible OpenSSL; host OpenSSL upgrades after the binary was built; CI runners with restrictive syscall filters.
Related errors
- failed to install rustls crypto provider
- mesh ready-registry publish failed: {e}
- failed to install rustls crypto provider
- HTTP client build must succeed
- mesh endpoint bind on {} failed: {e}
AI-assisted analysis of block/buzz@934f3325c3 (2026-08-20).
Data as JSON: /api/errors/929eac651313331b.
Report an issue: GitHub.