CORS errors and HTTPS redirect loops
The two configuration traps everyone hits once: the credentials-plus-wildcard CORS rejection, and the infinite http↔https redirect behind a load balancer.
Two configuration mistakes account for most CORS and HTTPS issues in fastapi-guard deployments. Each produces a distinctive symptom, and each has a one-line fix once you know what to look for.
Symptom: browser blocks every cross-origin response
The browser refuses every response from your API. DevTools shows a CORS error. The server returned a response. The browser rejected it before your JavaScript saw it.
The credentials + wildcard trap
When cors_allow_credentials=True and cors_allow_origins=["*"], the CORS spec forbids the browser from accepting the response. The server does not produce an error. It returns the response normally. The browser reads the combination of Access-Control-Allow-Origin: * and the presence of credentials (cookies, Authorization header), sees the mismatch, and rejects the response.
fastapi-guard does not runtime-assert against this combination. There is no server-side warning. The browser DevTools message looks like: CORS error: cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.
Fix: list explicit origins instead of the wildcard.
cors_allow_origins=[
"https://app.example.com",
"https://staging.example.com",
],
cors_allow_credentials=TrueOrigins are exact-match: scheme, host, and port all count. https://app.example.com and http://app.example.com are different origins. https://app.example.com:443 and https://app.example.com are the same origin (default port implied).
See Security headers & CORS for the full explanation.
Symptom: infinite http to https redirect
After enabling enforce_https=True, the browser loops. Every request redirects, which redirects again. The browser eventually stops with "too many redirects."
The trust_x_forwarded_proto fix
enforce_https returns a 301 redirect when it sees a plain HTTP request. Behind a load balancer that terminates TLS, the backend always receives plain HTTP, regardless of whether the original client was on HTTPS. Without trust_x_forwarded_proto=True, fastapi-guard cannot know the original request was HTTPS, so it redirects it. The redirect lands on the same load balancer, again as plain HTTP, and the loop begins.
The fix is trust_x_forwarded_proto=True. This tells fastapi-guard to trust the X-Forwarded-Proto header that the load balancer adds. When that header reads https, fastapi-guard treats the request as already secure and does not redirect it.
SecurityConfig(
enforce_https=True,
trust_x_forwarded_proto=True,
)trust_x_forwarded_proto is a narrower trust decision than trusted_proxies. It only affects scheme detection. It does not implicitly trust the full X-Forwarded-For chain. See Trusted proxies & client IP detection for the distinction.
The enforce_https behavior - 301 redirect, not 403 - and the trust_x_forwarded_proto pairing are documented in Passive mode vs fail-secure.
Preflight now goes through the security pipeline
As of fastapi-guard 6.0.0, CORS is handled directly by SecurityMiddleware rather than a separate Starlette CORSMiddleware. One consequence: OPTIONS preflight requests now pass through IP filtering, rate limiting, and detection before receiving a CORS response.
Before 6.0.0, preflights were handled by the external middleware and never reached the security pipeline. Banned IPs and rate-limited clients could send preflights freely. That gap is closed in 6.0.0.
If you upgraded from a version before 6.0.0 and preflights started getting blocked:
- Verify the sending origin is not in the ban list.
- Verify the sending IP is not tripping the rate limiter (preflight counts toward rate-limit checks).
- If you called
SecurityMiddleware.configure_cors(app, config)separately, that call is removed in 6.0.0. Delete it.
See Security headers & CORS for the 6.0.0 change details.
Related
- Security headers & CORS - CORS configuration fields, the credentials+wildcard trap, preflight pipeline change
- Passive mode vs fail-secure -
enforce_httpsbehavior (301) andtrust_x_forwarded_protopairing - Trusted proxies & client IP detection -
trust_x_forwarded_protoscope and proxy trust configuration