This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: axum-08-tower-cancellation-abort-drain

Axum 0.8 Request Cancellation Propagation & Client Disconnect Abort Drain

Mandates that Axum 0.8 request handlers, Tower middleware, and downstream database operations strictly honor HTTP/2 and HTTP/3 RST_STREAM disconnect signals. Prevents compute leaks, database connection pool starvation, and phantom transactional writes by enforcing Tokio cancellation propagation and RAII rollback semantics.

Prohibited Anti-Pattern: Spawning Unlinked Background Tasks and Ignoring Stream Teardown in Long-Running Handlers

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Axum 0.8 Request Cancellation Propagation & Client Disconnect Abort Drain - Mandates that Axum 0.8 request handlers, Tower middleware, and downstream database operations strictly honor HTTP/2 and HTTP/3 RST_STREAM disconnect signals. Prevents compute leaks, database connection pool starvation, and phantom transactional writes by enforcing Tokio cancellation propagation and RAII rollback semantics.
globs: src/**/*.rs
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/axum-08-tower-cancellation-abort-drain"
---

# Axum 0.8 Request Cancellation Propagation & Client Disconnect Abort Drain

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Spawning Unlinked Background Tasks and Ignoring Stream Teardown in Long-Running Handlers

## System Constraints
You are a Principal Rust Architect enforcing Axum 0.8 and Tower request lifecycle semantics. Mandate that all handlers, middleware, and IO pipelines cleanly abort execution when a client drops the connection or sends an HTTP/2 RST_STREAM. Disallow detached asynchronous tasks that outlive the client socket without an explicit, monitored background supervisor.

## Strict Guidelines
- Engineers MUST ALWAYS keep request-scoped asynchronous tasks bound to the Axum handler future so Tokio runtime drops downstream operations when the client disconnects.
- Engineers MUST NOT spawn detached `tokio::spawn` tasks inside handlers without explicitly linking them to a `tokio_util::sync::CancellationToken` or handling cooperative shutdown.
- Database transactions MUST rely on RAII automatic rollback upon future drop, rather than executing deferred commits in detached background tasks.
- Handlers executing long-lived CPU loops, external HTTP calls, or streaming bodies MUST cooperatively poll cancellation via `tokio::select!` or yield points.
- Components NEVER swallow cancellation errors or convert premature socket closures into partial successful state transitions.

## Bad vs Good Implementations
### Axum 0.8 Client Disconnect & SQL Transaction Cancellation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Detaching the database transaction with `tokio::spawn` decouples execution from the hyper/axum connection lifecycle. When an HTTP/2 client aborts via RST_STREAM, Axum drops the handler future, but the spawned task continues executing, exhausting connection pools and causing phantom writes.
```rust
use axum::{extract::State, http::StatusCode, response::IntoResponse, Json};
use serde::Deserialize;
use sqlx::PgPool;

#[derive(Deserialize)]
pub struct OrderPayload {
    pub user_id: i64,
    pub amount: i64,
}

// ANTI-PATTERN: Spawning unlinked background tasks ignores RST_STREAM disconnects.
// If the client cancels the HTTP/2 stream midway, this task continues burning
// connection pool resources and commits orphaned records.
pub async fn create_order(
    State(pool): State<PgPool>,
    Json(payload): Json<OrderPayload>,
) -> impl IntoResponse {
    tokio::spawn(async move {
        let mut tx = pool.begin().await.unwrap();
        sqlx::query!(
            "INSERT INTO orders (user_id, amount) VALUES ($1, $2)",
            payload.user_id,
            payload.amount
        )
        .execute(&mut *tx)
        .await
        .unwrap();
        
        // Lengthy third-party verification simulates high latency
        tokio::time::sleep(std::time::Duration::from_secs(5)).await;
        
        tx.commit().await.unwrap();
    });

    StatusCode::ACCEPTED
}
```

#### Production Standard (Correct)
> **Standard**: By executing the transaction directly within the handler's asynchronous lifecycle, any client-side RST_STREAM or socket termination drops the active future. Rust's RAII drop semantics guarantee that the `sqlx::Transaction` drops before commit, safely aborting downstream IO and returning the connection to the pool.
```rust
use axum::{extract::State, http::StatusCode, response::IntoResponse, Json};
use serde::Deserialize;
use sqlx::PgPool;
use tokio_util::sync::CancellationToken;

#[derive(Deserialize)]
pub struct OrderPayload {
    pub user_id: i64,
    pub amount: i64,
}

// PRODUCTION FIX: The future remains strictly inlined to the Axum handler.
// If the client disconnects (RST_STREAM), hyper drops the handler future,
// immediately dropping `tx` and triggering automatic PostgreSQL rollback via RAII.
pub async fn create_order(
    State(pool): State<PgPool>,
    Json(payload): Json<OrderPayload>,
) -> Result<impl IntoResponse, StatusCode> {
    let mut tx = pool.begin().await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    sqlx::query!(
        "INSERT INTO orders (user_id, amount) VALUES ($1, $2)",
        payload.user_id,
        payload.amount
    )
    .execute(&mut *tx)
    .await
    .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    // If client disconnects during this await, the entire stack frame unwinds,
    // dropping `tx` before commit, reliably rolling back uncommitted DB mutations.
    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    tx.commit().await.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok((StatusCode::CREATED, Json(serde_json::json!({ "status": "completed" }))))
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Axum 0.8 Request Cancellation Propagation & Client Disconnect Abort Drain

Axum 0.8 Request Cancellation Propagation & Client Disconnect Abort Drain defines an industrial-grade behavioral standard for backend engineering. Mandates that Axum 0.8 request handlers, Tower middleware, and downstream database operations strictly honor HTTP/2 and HTTP/3 RST_STREAM disconnect signals. Prevents compute leaks, database connection pool starvation, and phantom transactional writes by enforcing Tokio cancellation propagation and RAII rollback semantics. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Spawning Unlinked Background Tasks and Ignoring Stream Teardown in Long-Running Handlers Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftSpawning Unlinked Background Tasks and Ignoring Stream Teardown in Long-Running HandlersCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS keep request-scoped asynchronous tasks bound to the Axum handler future so Tokio runtime drops downstream operations when the client disconnects.

Engineers MUST ALWAYS keep request-scoped asynchronous tasks bound to the Axum handler future so Tokio runtime drops downstream operations when the client disconnects.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT spawn detached `tokio

Engineers MUST NOT spawn detached `tokio::spawn` tasks inside handlers without explicitly linking them to a `tokio_util::sync::CancellationToken` or handling cooperative shutdown.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Database transactions MUST rely on RAII automatic rollback upon future drop, rather than executing deferred commits in detached background tasks.

Database transactions MUST rely on RAII automatic rollback upon future drop, rather than executing deferred commits in detached background tasks.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Handlers executing long-lived CPU loops, external HTTP calls, or streaming bodies MUST cooperatively poll cancellation via `tokio

Handlers executing long-lived CPU loops, external HTTP calls, or streaming bodies MUST cooperatively poll cancellation via `tokio::select!` or yield points.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Components NEVER swallow cancellation errors or convert premature socket closures into partial successful state transitions.

Components NEVER swallow cancellation errors or convert premature socket closures into partial successful state transitions.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Axum 0.8 Request Cancellation Propagation & Client Disconnect Abort Drain critical for AI coding assistants?

Mandates that Axum 0.8 request handlers, Tower middleware, and downstream database operations strictly honor HTTP/2 and HTTP/3 RST_STREAM disconnect signals. Prevents compute leaks, database connection pool starvation, and phantom transactional writes by enforcing Tokio cancellation propagation and RAII rollback semantics. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Spawning Unlinked Background Tasks and Ignoring Stream Teardown in Long-Running Handlers) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Axum