SECURITY WARNING: Never run commands you don't understand. Always review code before execution. Use at your own risk.
Rust New Added 10 September 2026

Tokio: Cannot start a runtime from within a runtime

Something called block_on on a thread that is already driving the async runtime, which would deadlock the worker, so Tokio panics instead. The call is usually not yours: a blocking client such as reqwest::blocking, or a library helper that hides block_on, used from inside an async function.

Quick fix

Read the commands before running them. Anything that restarts a service, deletes data or changes permissions should be tried on a non-production system first.

Quick fix
// Wrong: a blocking client inside an async task
let body = reqwest::blocking::get(url)?.text()?;

// Right: the async client, awaited
let body = reqwest::get(url).await?.text().await?;

// Genuinely blocking work belongs on the blocking pool
let rows = tokio::task::spawn_blocking(move || heavy_sync_query(&conn)).await??;

// Calling async code from a sync thread that is not a worker
let handle = tokio::runtime::Handle::current();
std::thread::spawn(move || handle.block_on(async { do_work().await }));

// In a #[tokio::test], the test body is already inside the runtime
#[tokio::test]
async fn works() { assert!(fetch().await.is_ok()); }

# Find the hidden block_on
cargo tree -i tokio
grep -rn "block_on\|reqwest::blocking" src/

How to diagnose Rust errors

Rust's compiler errors are unusually helpful. They are closer to a code review than an error message. Almost all of them come from ownership (a value was moved and then used), borrowing (two mutable borrows, or a borrow outliving its owner), or trait resolution (the required bound is not satisfied). The productive habit is to read the error's notes and help sections in full and run rustc --explain on the code.

If the quick fix above does not resolve it, work through these steps. They apply to this whole class of error, not just to this one message, which is usually what saves the time.

  1. Run rustc --explain E0502 (or whichever code) for a worked explanation of the rule you violated.
  2. For borrow conflicts, shorten the borrow's scope first, introducing a block or binding the intermediate result, before reaching for Rc<RefCell<T>>.
  3. For moved-value errors, decide deliberately: clone (cost), borrow (lifetime), or restructure so ownership flows one way. Cloning to silence the compiler is fine early and worth revisiting later.
  4. For trait errors, read which bound is missing and where it is required. cargo tree -d finds duplicate crate versions, which cause "trait not implemented" errors between two identical-looking types.
  5. Use cargo clippy routinely; it catches idiom problems that later become borrow-checker fights.

Tools worth reaching for

  • rustc --explain
  • cargo clippy
  • cargo tree -d
  • cargo expand
  • RUST_BACKTRACE=1

Authoritative references

Primary documentation for this error, worth reading before applying any fix in production.

tokio.rs

Related Rust errors

See all 19 Rust errors →

Browse other categories

Something missing or wrong?

This entry is maintained by hand. If the fix is out of date, incomplete, or you have a better one, email a correction and it will be reviewed.