# API returns 401 with a valid token -  Authorization header stripped by the reverse proxy

## TL;DR
The credential is fine; the proxy is eating the Authorization header before it reaches your app. Log headers at the app to confirm, then tell the proxy to forward Authorization explicitly.

```text
API returns 401 with a valid token -  Authorization header stripped by the reverse proxy
```

## Use this when
- The same request returns 200 direct to the app but 401 through the proxy
- The credential works in one environment and 401s in another with a different proxy
- 401s started after a proxy, ingress, or CDN change with no app deploy
- Every authenticated endpoint 401s, not just one

## Not for this skill when
- The credential is actually expired or wrong (test it direct first)
- Only one endpoint 401s (that's app logic, not the proxy)
- The failure is on CORS preflight, which never carries Authorization by design

## Steps
1. Prove the header is missing at the app. Add temporary debug logging of incoming headers on the auth middleware, or call the app directly bypassing the proxy.
Expected: the direct request returns 200; the proxied one returns 401. That isolates the proxy.

2. For nginx, forward the header explicitly and reload:
```
proxy_set_header Authorization $http_authorization;
```
Also check for a line that blanks it, like proxy_set_header Authorization with an empty value. Retest after reload.
Expected: the 401s stop, and the app log shows the header arriving.

3. For Apache, the header is often dropped by default; enable it:
```
WSGIPassAuthorization On
```
For proxy setups, preserve it with a rewrite rule that exports HTTP_AUTHORIZATION from the incoming Authorization header.
Expected: same result, header arrives at the app.

4. Check each hop if there are several: CDN to load balancer to ingress to app. Test at each layer.
Expected: you find exactly one layer stripping it; fix that layer only.

5. Remove the debug header logging from step 1.
Expected: no credential material in logs going forward.

### Variant: header stripped only around CORS flows
The preflight never carries Authorization by design; the real request should. If the real request also loses it, the proxy is still the suspect, not CORS.

### Variant: Cloudflare or AWS ALB in front
ALB passes Authorization through; check your target group's app config, not the ALB. With Cloudflare, check transform rules and worker code that might drop or rewrite headers.

### Variant: 401 only for long tokens
A proxy header-size limit is truncating the value. Raise the header buffer settings rather than forwarding differently.

## Why this happens
Some proxies don't forward the Authorization header unless told to, a leftover from the CGI era when the header was considered sensitive. The app then sees an anonymous request and correctly returns 401. Everything looks right from the client's side because the client did send it.

## Edge cases and pitfalls
- A WAF rule can also strip or block the header; check WAF logs if the proxy config looks clean.
- If you terminate TLS at the proxy and re-encrypt to the app, the header must survive the second hop too.
- Don't fix this by moving the credential into a query parameter; that leaks it into logs everywhere.
- Underscores in custom header names get dropped by some proxies; Authorization itself is fine, but your X_Custom headers may not be.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_FwWQAC4DQRYCVt1J2GHLjA
