tokio-rs/tokio · error · syn::Error

The #[tokio::main] macro requires rt or rt-multi-thread.

Error message

The #[tokio::main] macro requires rt or rt-multi-thread.

What it means

Compile-time error from the `main_fail` proc-macro attribute, which Tokio aliases to `#[tokio::main]` when neither the `rt` nor `rt-multi-thread` Cargo feature is enabled (it always fails with this message). It is the runtime-less fallback so the macro produces a clear diagnostic instead of unresolved-symbol errors.

Source

Thrown at tokio-macros/src/lib.rs:634

/// #[tokio::test]
/// async fn my_test() {
///     assert!(true);
/// }
/// ```
#[proc_macro_attribute]
pub fn test_rt(args: TokenStream, item: TokenStream) -> TokenStream {
    entry::test(args.into(), item.into(), false).into()
}

/// Always fails with the error message below.
/// ```text
/// The #[tokio::main] macro requires rt or rt-multi-thread.
/// ```
#[proc_macro_attribute]
pub fn main_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
    syn::Error::new(
        proc_macro2::Span::call_site(),
        "The #[tokio::main] macro requires rt or rt-multi-thread.",
    )
    .to_compile_error()
    .into()
}

/// Always fails with the error message below.
/// ```text
/// The #[tokio::test] macro requires rt or rt-multi-thread.
/// ```
#[proc_macro_attribute]
pub fn test_fail(_args: TokenStream, _item: TokenStream) -> TokenStream {
    syn::Error::new(
        proc_macro2::Span::call_site(),
        "The #[tokio::test] macro requires rt or rt-multi-thread.",
    )
    .to_compile_error()
    .into()
}

View on GitHub (pinned to 625954f365)

Solutions

  1. Enable a runtime feature in Cargo.toml: `tokio = { version = "1", features = ["rt-multi-thread", "macros"] }`.
  2. For a single-threaded app, `features = ["rt", "macros"]` is sufficient.
  3. Run `cargo tree -e features -p tokio` to confirm the `rt`/`rt-multi-thread` feature is actually active.

Example fix

# before
tokio = { version = "1", features = ["macros"] }

# after
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
Defensive patterns

Strategy: validation

Validate before calling

// Verify in build.rs or a CI script that the rt feature is active:
// `cargo tree -e features -p tokio | grep -E '\b(rt|rt-multi-thread)\b'`

Prevention

When it happens

Trigger: Annotating `#[tokio::main]` on a function while `tokio` is a dependency without `features = ["rt"]` or `["rt-multi-thread"]`.

Common situations: `tokio = { version = "...", default-features = false }` with only `macros` enabled; disabling default features then forgetting to add an `rt` feature; conditional feature flags that drop `rt` on some target.

Related errors


AI-assisted analysis of tokio-rs/tokio@625954f365 (2026-08-11). Data as JSON: /api/errors/03c431d23bbb68fa. Report an issue: GitHub.