Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used by another runtime.
ID: rust/tokio-runtime-enter-error
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| tokio 1.35.0 | active | — | — | — |
| tokio 1.36.0 | active | — | — | — |
| tokio 1.37.0 | active | — | — | — |
| rustc 1.75.0 | active | — | — | — |
Root Cause
Attempting to create or enter a Tokio runtime (e.g., via `block_on`, `runtime.block_on`, or `#[tokio::main]`) while already inside an active Tokio runtime context on the same thread.
generic中文
在同一个线程上已经处于活跃的 Tokio 运行时上下文中时,尝试创建或进入另一个 Tokio 运行时(例如通过 `block_on`、`runtime.block_on` 或 `#[tokio::main]`)。
Official Documentation
https://docs.rs/tokio/latest/tokio/runtime/struct.Runtime.html#method.block_onWorkarounds
-
90% success Use `tokio::task::spawn_blocking` to run blocking code on a separate thread pool without creating a new runtime: `tokio::task::spawn_blocking(move || { /* blocking work */ }).await`
Use `tokio::task::spawn_blocking` to run blocking code on a separate thread pool without creating a new runtime: `tokio::task::spawn_blocking(move || { /* blocking work */ }).await` -
85% success Pass the runtime handle around using `tokio::runtime::Handle::current()` and use `handle.block_on()` only from non-async contexts; avoid calling `block_on` inside async code.
Pass the runtime handle around using `tokio::runtime::Handle::current()` and use `handle.block_on()` only from non-async contexts; avoid calling `block_on` inside async code.
-
95% success Restructure the code to use a single runtime: if you need to run blocking code, use `tokio::task::spawn_blocking`; if you need to call async code from sync code, use `tokio::runtime::Runtime::block_on` only at the top-level entry point.
Restructure the code to use a single runtime: if you need to run blocking code, use `tokio::task::spawn_blocking`; if you need to call async code from sync code, use `tokio::runtime::Runtime::block_on` only at the top-level entry point.
中文步骤
Use `tokio::task::spawn_blocking` to run blocking code on a separate thread pool without creating a new runtime: `tokio::task::spawn_blocking(move || { /* blocking work */ }).await`Pass the runtime handle around using `tokio::runtime::Handle::current()` and use `handle.block_on()` only from non-async contexts; avoid calling `block_on` inside async code.
Restructure the code to use a single runtime: if you need to run blocking code, use `tokio::task::spawn_blocking`; if you need to call async code from sync code, use `tokio::runtime::Runtime::block_on` only at the top-level entry point.
Dead Ends
Common approaches that don't work:
-
75% fail
If the spawned thread also tries to create a runtime, it will succeed on a new thread, but the original thread still has the nested runtime issue; also, sharing data across threads may require `Send + Sync`.
-
90% fail
This still attempts to enter a runtime from within another runtime on the same thread; the error persists.
-
80% fail
This can lead to multiple runtime instances and still cause the same error if any runtime is entered while another is active; it also complicates code structure.