{"record":{"id":"5f2d168b10f57bba","repo":"t8y2/dbx","slug":"failed-to-bind-address","errorCode":null,"errorMessage":"Failed to bind address","messagePattern":"Failed to bind address","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/dbx-web/src/main.rs","lineNumber":1125,"sourceCode":"\n    let static_dir = std::env::var_os(\"DBX_STATIC_DIR\").map(std::path::PathBuf::from);\n    app = mount_public_base_path(app, &public_base_path, static_dir.as_deref());\n\n    // Bind address\n    let port: u16 = std::env::var(\"DBX_PORT\").ok().and_then(|p| p.parse().ok()).unwrap_or(4224);\n    let addr = SocketAddr::from(([0, 0, 0, 0], port));\n\n    tracing::info!(\"DBX Web server starting on http://{}\", addr);\n    if public_base_path != \"/\" {\n        tracing::info!(\"Serving DBX Web under context path {}\", public_base_path);\n    }\n    if password_disabled {\n        tracing::info!(\"Password protection is disabled\");\n    } else if std::env::var(\"DBX_PASSWORD\").is_ok() {\n        tracing::info!(\"Password protection is enabled\");\n    }\n\n    let listener = tokio::net::TcpListener::bind(addr).await.expect(\"Failed to bind address\");\n    let shutdown_state = web_state.app.clone();\n    axum::serve(listener, app)\n        .with_graceful_shutdown(async {\n            if let Err(error) = tokio::signal::ctrl_c().await {\n                tracing::warn!(\"Failed to listen for shutdown signal: {error}\");\n            }\n        })\n        .await\n        .expect(\"Server error\");\n    shutdown_state.shutdown(std::time::Duration::from_secs(3)).await;\n}\n\n#[cfg(test)]\nmod tests {\n    use super::{\n        mount_public_base_path, normalize_public_base_path, web_agent_dir_from_env, web_body_limit_bytes_from_value,\n        web_compression_predicate, XLSX_CONTENT_TYPE,\n    };","sourceCodeStart":1107,"sourceCodeEnd":1143,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/crates/dbx-web/src/main.rs#L1107-L1143","documentation":"Panics/aborts in dbx-web main when binding the HTTP listener to 0.0.0.0:DBX_PORT (default 4224) fails — the port is already in use or lacks bind permissions. The server cannot accept connections, so startup terminates after logging the bind failure.","triggerScenarios":"TcpListener::bind(addr) fails because the port is already in use, the address is not a local interface, or the process lacks permission to bind (e.g., privileged port <1024 without capabilities).","commonSituations":"Another instance of dbx-web (or a leftover process) holding the port; DBX_HOST/DBX_PORT set to a bad or in-use combination; binding port 80/443 as non-root in a container; IPv6 address specified on a host without IPv6.","solutions":["Free the port: find and stop the process using it (lsof -i :PORT / netstat) or choose a different port via DBX_PORT.","Set DBX_HOST to 0.0.0.0 (or a valid local IP) and a non-privileged port, or grant binding capabilities.","Check IPv6 availability if binding '::' — use '0.0.0.0' on IPv4-only hosts.","Configure SO_REUSEADDR equivalent or ensure a graceful shutdown of the previous instance before restart."],"exampleFix":"// before\nlet listener = tokio::net::TcpListener::bind(addr).await.expect(\"Failed to bind address\");\n// after\nlet listener = tokio::net::TcpListener::bind(&addr).await\n    .unwrap_or_else(|e| panic!(\"Failed to bind address {}: {e}\", addr));","handlingStrategy":"validation","validationCode":"use std::net::TcpListener;\nfn port_free(addr: &str) -> bool {\n    addr.to_socket_addrs().ok()\n        .and_then(|mut a| a.next())\n        .map(|a| TcpListener::bind(a).is_ok())\n        .unwrap_or(false)\n}\n// call before starting: assert!(port_free(\"127.0.0.1:8080\"));","typeGuard":null,"tryCatchPattern":"match tokio::net::TcpListener::bind(&addr).await {\n    Ok(l) => l,\n    Err(e) if e.kind() == std::io::ErrorKind::AddrInUse => {\n        eprintln!(\"Port in use at {addr}; stop the other process or change DBX_PORT\");\n        std::process::exit(1);\n    }\n    Err(e) => { eprintln!(\"Failed to bind {addr}: {e}\"); std::process::exit(1); }\n}","preventionTips":["Check the port with lsof/netstat before deploying or restarting.","Use non-privileged ports (>1024) or grant binding capabilities.","Use 0.0.0.0 unless a specific interface is required.","Coordinate port allocation across replicas via env config."],"tags":["network","rust","tcp","bind","startup"],"backgroundTag":"address-in-use","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}