{"record":{"id":"e206c55171f99df2","repo":"getzola/zola","slug":"could-not-bind-to-address","errorCode":null,"errorMessage":"Could not bind to address","messagePattern":"Could not bind to address","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/serve.rs","lineNumber":651,"sourceCode":"    thread::spawn(move || {\n        let rt = tokio::runtime::Builder::new_current_thread()\n            .enable_all()\n            .build()\n            .expect(\"Could not build tokio runtime\");\n\n        rt.block_on(async {\n            let state = Arc::new(AppState { static_root, base_path, reload_tx });\n\n            let app = Router::new()\n                .route(\"/livereload.js\", get(serve_livereload_js))\n                .route(\"/livereload\", get(ws_handler))\n                .fallback(handle_request)\n                .layer(middleware::map_response(error_injection_middleware))\n                .with_state(state);\n\n            let listener = tokio::net::TcpListener::bind(&bind_address)\n                .await\n                .expect(\"Could not bind to address\");\n\n            let local_addr = listener.local_addr().unwrap();\n\n            log::info!(\n                \"Web server is available at {} (bound to {})\\n\",\n                constructed_base_url.replace(&bind_address.to_string(), &local_addr.to_string()),\n                local_addr\n            );\n            if open && let Err(err) = open::that(&constructed_base_url) {\n                log::error!(\"Failed to open URL in your browser: {err}\");\n            }\n\n            axum::serve(listener, app).await.expect(\"Could not start web server\");\n        });\n    });\n\n    // We watch for changes in the config by monitoring its parent directory, but we ignore all\n    // ordinary peer files. Map the parent directory back to the config file name to not confuse","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/getzola/zola/blob/61d30828217957120309db657950224edf9707e2/src/cmd/serve.rs#L633-L669","documentation":"Inside the spawned server thread, serve() awaits tokio::net::TcpListener::bind(&bind_address) and expects success. The expect fires when the configured address/port cannot be bound — most commonly the port is already in use by another process, or the user lacks permission for the port (privileged ports <1024) or the interface does not exist. Earlier in serve() a synchronous TcpListener::bind probe already ran; this is the actual async bind the server depends on, so failure means the dev server cannot listen.","triggerScenarios":"Thrown at src/cmd/serve.rs:651 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Free the port: stop the other process listening on bind_address (lsof/netstat can identify it)","Choose a different port via the --port flag or let the OS pick a free port","Avoid privileged ports below 1024 or run with sufficient permissions","Replace expect() with an anyhow error that includes bind_address and the underlying io::Error"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"61d30828217957120309db657950224edf9707e2","analyzedAt":"2026-09-03T14:39:09.727Z","contentChangedAt":"2026-09-03T14:39:09.727Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}