首先说一下前提:
自己搭建的 sub2api 用 codex 上请求不上,但是站上其他人的公益站的 sub2api 的却可以,主要体现在/v1/responses 的请求不通,但是使用 curl 发请求却是可以的。
先是查了一下站上有人问没,有说不用代理的,有说没加 /v1的,翻了几个和我情况也不太相符,于是问 ai:
他先让我看我的 sub2api 是否真的支持 /v1/responses,用 curl 请求非流式和流式,判断是不是这个的问题;我试了没问题都有返回。
然后让我看是不是 nginx 配置 的问题,发现多了静态网站配置的,让我删了排除干扰;顺便排除 cf 没开小黄云;改完以后测试发现还是有问题。于是再问它。
nginx 改好了,重启了,还是这样。先• Reconnecting... 2/5 (16s • esc to interrupt)
└ Stream disconnected before completion: error sending request for url (https://xxx/v1/responses)
最后■ stream disconnected before completion: error sending request for url (https://xxx/v1/responses)
他判断是:
请求阶段/连接阶段就出问题了。
也就是说,Codex 甚至可能还没稳定进入“正常接收流”的阶段。
让我检查全链路问题:
- 确认是否经过 Cloudflare;
- 把 HTTP/3 / QUIC 彻底关掉,
别让客户端有机会走 HTTP/3,只保留
listen 443 ssl;
listen [::]:443 ssl;
- 强制测 HTTP/1.1 和 HTTP/2
- 直接看 Nginx access/error log
- 从服务器本机测,不走公网绕路
都测了发现都正常,又判断是不是域名证书有问题,因为返回有点不同。openssl s_client -connect 域名:443 -servername 域名,测了发现证书没问题。
上面一通查证,发现都正常。它说最后该怎么办呢?现在最有效的排查方式,不是继续猜,而是抓“真实请求”:
给 nginx 增强 access log,重点看用 codex 发消息后nginx 日志的打印情况。
最终发现了问题了关键点:
2026/04/13 14:57:58 [info] 28#28: *70 SSL_do_handshake() failed (SSL: error:0A000102:SSL routines::unsupported protocol) while SSL handshaking, client: xxxx, server: 0.0.0.0:443
2026/04/13 14:57:59 [info] 28#28: *71 SSL_do_handshake() failed (SSL: error:0A000102:SSL routines::unsupported protocol) while SSL handshaking, client: xxx, server: 0.0.0.0:443
2026/04/13 14:58:00 [info] 28#28: *72 SSL_do_handshake() failed (SSL: error:0A000102:SSL routines::unsupported protocol) while SSL handshaking, client: xxxx, server: 0.0.0.0:443
它 优先怀疑 TLS/代理兼容问题。看 nginx 里是否有ssl_protocols TLSv1.2 TLSv1.3; 看了一下我的还真没有!!
最终给了我建议, 80 和 443 混在一个 server 里,虽然能跑,但不够干净
改造后的配置:
upstream backend_GduktARz {
server sub2api:8080;
keepalive 64;
}
# 80 端口:纯跳转
server {
listen 80;
listen [::]:80;
server_name 域名;
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
}
location / {
return 301 https://$host$request_uri;
}
}
# 443 端口:正式 HTTPS
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name 域名;
ssl_certificate /etc/nginx/certs/xxxx.pem;
ssl_certificate_key /etc/nginx/certs/xxxx.pem;
# 关键:明确支持 TLS 1.2 / 1.3
ssl_protocols TLSv1.2 TLSv1.3;
client_max_body_size 1000m;
access_log /dev/stdout;
error_log /dev/stderr info;
# 专门给 Responses SSE
location = /v1/responses {
proxy_pass http://backend_GduktARz;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_buffering off;
proxy_request_buffering off;
proxy_cache off;
gzip off;
# SSE 一般别乱折腾 chunked,保持现在这样问题不大
chunked_transfer_encoding off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
send_timeout 3600s;
add_header Cache-Control "no-cache" always;
add_header X-Accel-Buffering "no" always;
}
# 其他 API
location /v1/ {
proxy_pass http://backend_GduktARz;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
# 兜底
location / {
proxy_pass http://backend_GduktARz;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
}
}
改了后发现正常了!!我的 codex 可以正常回复了!!
花了一下午的时间,发现终于好了。
最后结论总结采用及更改:
- 显式开启 HTTP/2
- 显式声明 TLS 版本
- 在
/v1/responses保持流式友好配置 - 拆分 80 / 443 server(不是主因)
最终结论:
Nginx 在 HTTPS/TLS/HTTP2 连接层面的配置不够明确,导致部分客户端连接协商失败,进而表现为客户端请求发送失败和流式响应中断。
后语:
现在的 ai 时代还是太超前了,想几年前如果遇到这种问题,不熟悉这个领域的根本解决不了。还是感谢人类的伟大创造。后面有人如果遇到可以参考一下(大概率遇不到 ![]()
![]()
)
2 个帖子 - 2 位参与者