{"record":{"id":"bc2bee53f111cbf9","repo":"block/buzz","slug":"mesh-endpoint-bind-on-failed-e","errorCode":null,"errorMessage":"mesh endpoint bind on {} failed: {e}","messagePattern":"mesh endpoint bind on (.+?) failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"crates/buzz-relay/src/mesh_boot.rs","lineNumber":426,"sourceCode":"/// sets `BUZZ_MESH=on` wants the mesh or wants to know why not; silently\n/// booting meshless would be the same class of bug as silently dropping to a\n/// default tenant.\npub async fn boot_mesh(\n    config: &Config,\n    redis_pool: deadpool_redis::Pool,\n    db: buzz_db::Db,\n    relay_keypair: &nostr::Keys,\n    shutting_down: Arc<AtomicBool>,\n) -> anyhow::Result<Option<MeshHandle>> {\n    if !config.mesh.enabled {\n        tracing::info!(\"mesh disabled (BUZZ_MESH is not 'on') — single-instance behavior\");\n        return Ok(None);\n    }\n\n    let endpoint = MeshEndpoint::bind(config.mesh.bind_addr)\n        .await\n        .map_err(|e| {\n            anyhow::anyhow!(\n                \"mesh endpoint bind on {} failed: {e}\",\n                config.mesh.bind_addr\n            )\n        })?;\n    let runtime_id = endpoint.runtime_id();\n    let addrs = advertise_addrs(&endpoint);\n    tracing::info!(\n        runtime_id = %runtime_id,\n        bind_addr = %config.mesh.bind_addr,\n        advertise_addrs = ?addrs,\n        \"mesh endpoint bound\"\n    );\n\n    let mut local_record = GossipRecord::new(runtime_id, addrs.clone(), PROTO_VERSION);\n    local_record.capabilities = capabilities();\n    // Anchor ready-record acceptance to this deployment's relay identity: all\n    // pods share the relay signing key, so a seed attested by any other key is\n    // foreign and rejected (Wren's review — possession is not authorization).","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/block/buzz/blob/934f3325c3fdaa3a6f23134b74518139aac8ca3f/crates/buzz-relay/src/mesh_boot.rs#L408-L444","documentation":"When BUZZ_MESH=on, mesh_boot binds an iroh QUIC/UDP endpoint (MeshEndpoint::bind → iroh Endpoint::builder().bind_addr(addr).bind()) on config.mesh.bind_addr (BUZZ_MESH_BIND_ADDR, see config.rs:608). A bind failure is wrapped with the address and mesh boot aborts, which fails relay startup — the relay refuses to run a half-meshed instance.","triggerScenarios":"The iroh endpoint bind at crates/buzz-relay/src/mesh_boot.rs:423 fails when: (1) the UDP port in BUZZ_MESH_BIND_ADDR is already bound by another relay/mesh instance (AddrInUse — note UDP, so `ss -ltn` will not show it); (2) the address family/IP does not exist on the host (EADDRNOTAVAIL); (3) privileged UDP port without CAP_NET_BIND_SERVICE; (4) firewall/SELinux denying UDP bind.","commonSituations":"Two relay replicas configured with the same BUZZ_MESH_BIND_ADDR on one host (staging ArgoCD rollout where old pod overlaps with new); BUZZ_MESH_BIND_ADDR copied from the Terraform stack with a VPC IP that does not exist on the node; local dev with a leftover relay process still holding the UDP socket.","solutions":["Check the UDP listener: `ss -lunp 'sport = :<port>'` and stop the duplicate process/pod.","Set BUZZ_MESH_BIND_ADDR to 0.0.0.0:<port> (or a free port) and restart.","Verify the IP in BUZZ_MESH_BIND_ADDR exists on the host (`ip addr`).","If mesh is not needed for this deployment, set BUZZ_MESH to something other than 'on' — mesh_boot then logs 'mesh disabled' and returns Ok(None)."],"exampleFix":"# before\nBUZZ_MESH=on\nBUZZ_MESH_BIND_ADDR=10.2.3.4:7777  # IP absent on this node\n\n# after\nBUZZ_MESH=on\nBUZZ_MESH_BIND_ADDR=0.0.0.0:7777","handlingStrategy":"validation","validationCode":"# UDP ports need -u; verify mesh bind is free before enabling mesh\nif ss -lunH \"sport = :${BUZZ_MESH_BIND_ADDR##*:}\" | grep -q .; then\n  echo \"mesh UDP port busy\" >&2; exit 1\nfi\n[ \"${BUZZ_MESH:-off}\" = \"on\" ] || echo \"mesh off — bind not required\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember mesh binds UDP, not TCP — check with `ss -lun`, regular TCP checks will miss conflicts.","Use port 0 or 0.0.0.0:0 for dev mesh instances to let the OS assign a free port when discovery port does not matter.","Give each replica its own BUZZ_MESH_BIND_ADDR in host-networked deployments.","Leave BUZZ_MESH off for single-instance local dev — mesh_boot then skips binding entirely."],"tags":["rust","network","udp","quic","iroh","mesh","startup","port-bind"],"backgroundTag":"udp-bind-failed","analyzedSha":"934f3325c3fdaa3a6f23134b74518139aac8ca3f","analyzedAt":"2026-08-20T04:38:24.874Z","contentChangedAt":"2026-08-20T04:38:24.874Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}