{"record":{"id":"b418913d9d83fdc9","repo":"getzola/zola","slug":"could-not-start-web-server","errorCode":null,"errorMessage":"Could not start web server","messagePattern":"Could not start web server","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/serve.rs","lineNumber":664,"sourceCode":"                .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\n    // the end user.\n    let config_name =\n        config_path.file_name().unwrap().to_str().expect(\"Config name is not valid UTF-8.\");\n    let watch_list = watchers\n        .iter()\n        .map(|w| if w == root_dir_str { config_name } else { w })\n        .collect::<Vec<&str>>()\n        .join(\",\");\n    log::info!(\n        \"Listening for changes in {}{}{{{}}}\",\n        root_dir.display(),\n        MAIN_SEPARATOR,\n        watch_list","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/getzola/zola/blob/61d30828217957120309db657950224edf9707e2/src/cmd/serve.rs#L646-L682","documentation":"serve() reaches axum::serve(listener, app).await and expects the server loop to start (and, since .await is expected, to keep serving) without error. The expect fires if axum::serve returns an error while starting or accepting connections — e.g. the listener was closed underneath the server, an OS-level socket error occurred, or the runtime is being torn down. At this point binding already succeeded, so this panic indicates the accepted listener became unusable rather than a bad address.","triggerScenarios":"Thrown at src/cmd/serve.rs:664 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Investigate why the bound listener became invalid (external close, fd exhaustion)","Check OS socket limits (ulimit -n) if the error occurs under many connections","Replace expect() with a logged error and graceful shutdown so a running site is not killed abruptly","Ensure nothing else in the process closes or steals the listener fd"],"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"}