Skip to main content

Configuring AsyncExitStackMiddleware

FastAPI uses AsyncExitStackMiddleware to manage the lifecycle of resources that must be cleaned up after a request is finished, most notably closing temporary files created during multipart form uploads.

While FastAPI adds this middleware automatically to every application, you can manually initialize and configure it if you need to customize the context name used in the ASGI scope.

Add AsyncExitStackMiddleware Manually

You can add AsyncExitStackMiddleware to your FastAPI application using the add_middleware method. This is typically only necessary if you want to change the context_name or if you are building a custom ASGI stack.

from fastapi import FastAPI
from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware

app = FastAPI()

# Add the middleware manually with a custom context name
app.add_middleware(AsyncExitStackMiddleware, context_name="custom_astack")

@app.get("/")
async def root():
return {"message": "Hello World"}

The context_name Parameter

The context_name parameter (defined in fastapi/middleware/asyncexitstack.py) determines the key used to store the contextlib.AsyncExitStack instance within the ASGI scope dictionary.

  • Default: "fastapi_middleware_astack"
  • Purpose: It allows other components (like routers or dependencies) to retrieve the stack from the request scope and register cleanup callbacks.

Automatic Middleware Integration

In standard usage, you do not need to add this middleware yourself. FastAPI automatically includes it in the middleware stack within fastapi/applications.py.

FastAPI positions AsyncExitStackMiddleware specifically within the stack to ensure it runs after user-defined middlewares. This placement ensures that any contextvars set within the middleware are preserved correctly, which was historically important for dependencies using yield.

# Internal FastAPI implementation in fastapi/applications.py
middleware = (
[Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)]
+ self.user_middleware
+ [
Middleware(
ExceptionMiddleware,
handlers=exception_handlers,
debug=debug,
),
# Add FastAPI-specific AsyncExitStackMiddleware for closing files.
Middleware(AsyncExitStackMiddleware),
]
)

Troubleshooting and Constraints

Internal Lookup Failures

If you change the context_name to something other than the default "fastapi_middleware_astack", internal FastAPI routing will fail when handling file uploads.

The routing logic in fastapi/routing.py contains a hardcoded lookup for this specific key to manage file cleanup:

# From fastapi/routing.py
file_stack = request.scope.get("fastapi_middleware_astack")
assert isinstance(file_stack, AsyncExitStack), (
"fastapi_middleware_astack not found in request scope"
)

If the middleware is configured with a different name, the assertion will fail, and FastAPI will be unable to process requests that involve UploadFile or form data.

Scope of Responsibility

AsyncExitStackMiddleware is primarily responsible for closing files. Modern FastAPI versions (0.117.1 and later) use a separate internal AsyncExitStack for dependencies that use yield to better support streaming responses and context propagation. Consequently, this middleware is now focused almost exclusively on ensuring that UploadFile objects are properly closed after the response is sent.