AAD Token 太大讓 nginx HTTP/2 直接 GOAWAY

前言

在最近的專案中,心血來潮在所有呼叫公司內部 API 的 header 都加上 AAD token, 結果其中一個服務的 API 直接掛掉,從瀏覽器中只看到 ERR_CONNECTION_CLOSED,而後端用 Swagger 測試正常,去看 Nginx 的 Access log 和 Error log 都沒有紀錄。

奇怪到底發生什麼事?

除錯過程

已知線索

目前已知的線索有:

  1. Preflight 有過
  2. Swagger 可以通但是從應用程式送請求會沒有回應
  3. Nginx 的 Access Log 和 Error Log 都沒有紀錄

初步懷疑

懷疑的幾種可能:

  1. 有人改到 Access-Control-Allow-Origin header 讓 CORS 請求不會過
  2. 公司的 Proxy 攔截到 AAD token 後做了什麼事
  3. Load Balancer 或是 Nginx 出問題

抓到 GOAWAY

測試的過程使用 Opencode 搭配 Opus 來說真的非常爽快,對於我提出的懷疑這個組合都能夠直接使用指令來測試,在用 Curl 帶 Token 測試的過程中,發現了新的線索:

1
2
3
4
5
6
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* received GOAWAY, error=11, last_stream=1
* TLSv1.3 (IN), TLS alert, close notify (256):
* Closing connection

看到了關鍵字 GOAWAY 以及 error=11 代表 ENHANCE_YOUR_CALM ,這個是 HTTP/2 中,伺服器認為用戶端可能會造成負載過高,通知用戶端即將關閉連線。

確認 nginx buffer 設定

有了這個線索後,可以懷疑是 Nginx 的問題,因為是加了 header 打不過,在 Config 中看到了亮點:

1
2
client_header_buffer_size 1k;
large_client_header_buffers 2 1k;

分別做了以下兩個測試分別都通過了

  1. 在應用程式前端中拿掉 Bearer token 後呼叫 API
  2. 在後端把 buffer size 加大

測試 header 大小

後來又多做了幾個測試來測不同 header 大小

1
2
3
4
5
6
for SIZE in 500 1000 1500 2000; do
TOKEN=$(python3 -c "print('a'*$SIZE)")
CODE=$(curl -s --max-time 5 -o /dev/null -w "%{http_code}" --http2 \
'https://api.example.com/health' -H "Authorization: Bearer $TOKEN")
echo "size=${SIZE}B -> HTTP=$CODE"
done

發現 2000 以下的都可以通過,至於 1500 為什麼可以通過猜測是有經過壓縮,但我沒有驗證。

到這邊可以確認 Root Cause 就是 Nginx 的 large_client_header_buffers 上限被踩到,造成連線中斷。

HTTP/1.1 對照

有趣的是,如果我們強制使用 HTTP/1.1 連線,會得到 400 而且明確標示 Request Header Or Cookie Too Large

1
2
3
4
5
6
7
8
9
10
11
12
13
< HTTP/1.1 400 Bad Request
< Server: nginx/1.25.5
< Content-Type: text/html
< Connection: close

<html>
<head><title>400 Request Header Or Cookie Too Large</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>Request Header Or Cookie Too Large</center>
<hr><center>nginx/1.25.5</center>
</body>
</html>

小丑竟是我自己

這次的問題不好查有一部分原因是 GOAWAY 這個 frame 在瀏覽器根本不會顯示,加上 Nginx 沒有 log 可以看,只能旁敲側擊。

好在現在用 AI 來除錯真的很方便快速,所有工具唾手可得很快就能驗證想法。

後來去看了為什麼 buffer size 會被改成 1K,git blame 結果居然是我自己用 AI 產的 config…

再次驗證了 AI 寫出來的東西每一行都還是要看懂。

Reference


AAD Token 太大讓 nginx HTTP/2 直接 GOAWAY
https://weiblog.me/2026-06-24/2026-nginx-http2-large-client-header-buffers/
Author
wei
Posted on
June 24, 2026
Licensed under