This is an issue when CORSMiddleware is added to a FastAPI application and then followed by additional middleware using
add_middleware().
In FastAPI, middleware is executed in reverse order of how it’s added to the application. When you call app.add_middleware(), each
middleware wraps the previous one, forming a stack.
Think of it like wrapping a gift: the first layer you add becomes the innermost layer, and the last layer you add becomes the outermost layer. When processing a request, FastAPI starts from the outermost layer and works its way in.
CORS (Cross-Origin Resource Sharing) middleware needs to add specific HTTP headers to responses to allow browsers to make cross-origin requests. For these headers to be present on all responses - including those modified by other middleware - CORSMiddleware must be the outermost layer.
If you add other middleware after CORSMiddleware, those middleware will wrap around it and process requests/responses outside of the CORS layer. This means:
When CORSMiddleware is not positioned correctly, cross-origin requests from web browsers will fail. This breaks the functionality of web applications that need to make API calls from a different domain.
Users will see errors in their browser console, and features that depend on cross-origin requests will not work. This can affect:
Move the CORSMiddleware configuration to be the last add_middleware() call in your application setup. Add all other
middleware before adding CORSMiddleware.
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(GZipMiddleware) # Noncompliant
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
app = FastAPI()
app.add_middleware(GZipMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)