RightNow-AI/openfang · critical

Failed to create tokio runtime for embedded server

Error message

Failed to create tokio runtime for embedded server

What it means

This panic comes from an `.expect()` in start_server (crates/openfang-desktop/src/server.rs:94) when `tokio::runtime::Builder::new_multi_thread().enable_all().build()` returns an Err. The code spawns a dedicated OS thread and builds a fresh multi-threaded tokio runtime on it to run the embedded axum server, since tokio::spawn-based background agents require a runtime context. Runtime construction can fail because the builder cannot spawn worker threads or initialize internal resources (I/O or time drivers, parking/condvar primitives).

Source

Thrown at crates/openfang-desktop/src/server.rs:94

    // Bind to a random free port on localhost (main thread — guarantees port)
    let std_listener = TcpListener::bind("127.0.0.1:0")?;
    let port = std_listener.local_addr()?.port();
    let listen_addr: SocketAddr = std_listener.local_addr()?;

    info!("OpenFang embedded server bound to http://127.0.0.1:{port}");

    let (shutdown_tx, shutdown_rx) = watch::channel(false);
    let kernel_clone = kernel.clone();
    let shutdown_initiated = Arc::new(AtomicBool::new(false));

    let server_thread = std::thread::Builder::new()
        .name("openfang-server".into())
        .spawn(move || {
            let rt = tokio::runtime::Builder::new_multi_thread()
                .enable_all()
                .build()
                .expect("Failed to create tokio runtime for embedded server");

            rt.block_on(async move {
                // start_background_agents() uses tokio::spawn, so it must
                // run inside a tokio runtime context.
                kernel_clone.start_background_agents();
                run_embedded_server(kernel_clone, std_listener, listen_addr, shutdown_rx).await;
            });
        })?;

    Ok(ServerHandle {
        port,
        kernel,
        shutdown_tx,
        server_thread: Some(server_thread),
        shutdown_initiated,
    })
}

View on GitHub (pinned to acf2587e46)

Solutions

  1. Check OS resource limits (ulimit -u threads, ulimit -n file descriptors) and raise them for the process.
  2. Reduce worker thread pressure: configure .worker_threads(N) with a small N to lower thread creation cost.
  3. Ensure the process is not near its memory/thread budget before start_server is called (leaked threads from earlier failures).
  4. Replace the expect with proper error propagation (return Result from start_server) and surface the underlying io::Error to logs for diagnosis.
  5. Verify tokio crate version/features are consistent across the workspace to avoid driver initialization issues.

Example fix

// before
let rt = tokio::runtime::Builder::new_multi_thread()
    .enable_all()
    .build()
    .expect("Failed to create tokio runtime for embedded server");
// after
let rt = tokio::runtime::Builder::new_multi_thread()
    .enable_all()
    .worker_threads(2)
    .build()
    .map_err(|e| ServerError::RuntimeInit(e.to_string()))?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Before spawning the server thread, probe resource headroom
let max_threads = unsafe { libc::sysconf(libc::_SC_THREAD_THREADS_MAX) };
if max_threads != -1 && max_threads < 8 {
    return Err("too few threads allowed for tokio runtime");
}

Try / catch

let rt = tokio::runtime::Builder::new_multi_thread()
    .enable_all()
    .build();
match rt {
    Ok(rt) => { /* block_on(...) */ }
    Err(e) => log::error!("tokio runtime init failed: {e}"), // propagate to UI/notification
}

Prevention

When it happens

Trigger: Calling tokio Runtime::build() inside the spawned 'openfang-server' thread when the OS refuses to create worker threads (thread count/RLIMIT limits, out of memory), or when the tokio io/time driver resources cannot be created (e.g. epoll/kqueue fd exhaustion).

Common situations: Host environments with very low thread or file-descriptor limits (containers, CI sandboxes), heavily memory-constrained machines, or misconfigured tokio features (missing 'rt-multi-thread'/'macros' features is caught at compile time, but runtime resource exhaustion hits here).

Related errors


AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02). Data as JSON: /api/errors/46712d4b6d316e38. Report an issue: GitHub.