getzola/zola · error

Could not build tokio runtime

Error message

Could not build tokio runtime

What it means

serve() spawns a dedicated thread that builds a single-threaded tokio runtime via tokio::runtime::Builder::new_current_thread().enable_all().build().expect(...). The expect fires when runtime construction fails, which is practically limited to cases like running inside an existing tokio runtime context, resource exhaustion, or an unsupported platform/backend — without a runtime the Axum server thread cannot run at all, so the process aborts that thread.

Source

Thrown at src/cmd/serve.rs:637

        }
    }

    let output_path = site.output_path.clone();
    create_directory(&output_path)?;

    // static_root needs to be canonicalized because we do the same for the http server.
    let static_root = std::fs::canonicalize(&output_path).unwrap();

    // Create broadcast channel for WebSocket live reload
    let (reload_tx, _) = broadcast::channel::<String>(100);
    let broadcaster = reload_tx.clone();

    // Start Axum server in a separate thread
    thread::spawn(move || {
        let rt = tokio::runtime::Builder::new_current_thread()
            .enable_all()
            .build()
            .expect("Could not build tokio runtime");

        rt.block_on(async {
            let state = Arc::new(AppState { static_root, base_path, reload_tx });

            let app = Router::new()
                .route("/livereload.js", get(serve_livereload_js))
                .route("/livereload", get(ws_handler))
                .fallback(handle_request)
                .layer(middleware::map_response(error_injection_middleware))
                .with_state(state);

            let listener = tokio::net::TcpListener::bind(&bind_address)
                .await
                .expect("Could not bind to address");

            let local_addr = listener.local_addr().unwrap();

            log::info!(

View on GitHub (pinned to 61d3082821)

Solutions

  1. Ensure the server thread is not spawned from within an async/tokio context that forbids nested runtimes
  2. Check for resource limits (thread/memory) on the host if build() fails
  3. Propagate the io::Error as a logged anyhow error instead of expect() so the failure reason is reported
  4. Pin a known-good tokio version and verify platform support for the current-thread driver
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/cmd/serve.rs:637 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of getzola/zola@61d3082821 (2026-09-03). Data as JSON: /api/errors/5a00f53db8015d1d. Report an issue: GitHub.