Skip to content

输入关键词开始搜索

VS Code Remote SSH + Claude Code + CCSwitch + 智谱 GLM:400/1210 故障排查记录

本文记录一次 VS Code Remote SSH + Claude Code + CCSwitch + 智谱 GLM 环境中的完整故障排查过程。

最终故障表现为:

Claude Code VS Code 面板
发送“你好”
API Error: 400 [1210]
[API 调用参数有误,请检查文档。]

但问题并不是一个单点故障。

整个排查过程中,先后出现了:

SSH ReverseForward 端口被旧连接占用
15721 / 17890 反向隧道失效
VS Code 扩展网络异常
隧道恢复
Claude Code CLI 可以正常调用
VS Code Claude Code 仍然 400 / 1210
通过版本和 entrypoint 对照实验
最终定位到 Claude Code 2.1.267 的 claude-vscode 路径兼容回归
降级到 2.1.263
恢复正常

这次排障最有价值的地方,不是记住某一条命令,而是学会把复杂链路拆成多个可以独立验证的环节。

---

当前环境可以抽象成:

Windows 本地
├─ Clash
│ └─ 127.0.0.1:7897
├─ CCSwitch
│ └─ 127.0.0.1:15721
│ ↓
│ 智谱 GLM Anthropic 兼容接口
└─ VS Code
↓ SSH
Ubuntu 服务器
├─ 127.0.0.1:17890
│ └─ SSH RemoteForward
│ → Windows 127.0.0.1:7897
├─ 127.0.0.1:15721
│ └─ SSH RemoteForward
│ → Windows 127.0.0.1:15721
└─ Claude Code
ANTHROPIC_BASE_URL=http://127.0.0.1:15721

SSH 配置中关键部分为:

Host 192.168.198.10
HostName 192.168.198.10
User liangyc
RemoteForward 17890 127.0.0.1:7897
RemoteForward 15721 127.0.0.1:15721

两个反向端口分别承担不同功能:

17890:
服务器网络请求
Windows Clash
15721:
服务器 Claude Code
Windows CCSwitch
智谱 GLM

因此排查时必须把:

SSH
代理
CCSwitch
Claude Code
智谱 API
VS Code 扩展

分开验证。

---

2. 最初现象:VS Code 能连服务器,但扩展状态异常

Section titled “2. 最初现象:VS Code 能连服务器,但扩展状态异常”

最初 VS Code Remote SSH 已经可以连接服务器。

表现为:

文件浏览正常
终端正常
SSH 登录正常

但同时出现:

远程扩展加载异常
Claude Code 面板卡住
Codex / Claude Code 相关扩展状态不正常

第一反应很容易怀疑:

磁盘满了
inode 满了
.vscode-server 损坏
Extension Host 崩了

因此先检查服务器基础状态。

---

检查:

Terminal window
df -h
df -i
du -sh ~/.vscode-server

结果显示:

系统盘仍有可用空间
/data 空间充足
inode 使用率很低
~/.vscode-server 虽然较大,但没有达到无法工作的程度

因此:

磁盘空间不足 ❌
inode 耗尽 ❌

不再作为主要方向。

这一步很重要,因为如果没有先排除基础资源问题,后面很容易在 .vscode-server 上做无意义的删除和重装。

---

4. 发现多个旧 VS Code / SSH / Claude 进程

Section titled “4. 发现多个旧 VS Code / SSH / Claude 进程”

继续检查:

Terminal window
ps -ef | grep -E 'vscode|claude|codex'

发现服务器中存在多个:

VS Code Server
Extension Host
Claude Code
Codex
ssh user session

其中还有不同时间启动的旧会话。

进一步查看 SSH 监听:

Terminal window
ss -lntp | grep -E '15721|17890'

可以看到:

127.0.0.1:15721
127.0.0.1:17890
[::1]:15721
[::1]:17890

端口看起来“存在”,但这并不代表链路真的可用。

---

5. 关键现象:端口在监听,但请求会卡死

Section titled “5. 关键现象:端口在监听,但请求会卡死”

在服务器测试:

Terminal window
curl -v --max-time 5 http://127.0.0.1:15721/

以及:

Terminal window
curl -v --max-time 5 http://127.0.0.1:17890/

最初表现为:

TCP 可以 connect
但一直没有返回数据
最终 timeout

这说明:

端口监听存在
反向隧道可用

这类情况很容易误导排障。

如果只看:

Terminal window
ss -lnt

会认为“端口是好的”。

但真正重要的是:

能否建立连接
+
建立后能否完成实际请求

---

6. Remote SSH 日志给出第一个决定性线索

Section titled “6. Remote SSH 日志给出第一个决定性线索”

查看 VS Code Remote SSH 日志后,发现连接建立时出现:

Warning: remote port forwarding failed for listen port 17890
Warning: remote port forwarding failed for listen port 15721

这说明新的 SSH 会话尝试创建:

服务器 17890
服务器 15721

时失败。

最合理的解释是:

这些端口已经被旧 SSH 会话占用

于是继续查看当前用户的 SSH 连接。

---

7. 找到旧 SSH 会话占用了 ReverseForward 端口

Section titled “7. 找到旧 SSH 会话占用了 ReverseForward 端口”

服务器上存在多个:

sshd: liangyc@notty

旧会话。

这些旧连接建立时创建了:

127.0.0.1:15721
127.0.0.1:17890

但本地对应连接已经失效,因此形成了:

端口仍在监听
实际转发目标已经不可用
curl 可以 connect
但请求卡住

于是终止旧 SSH 会话。

示意:

Terminal window
kill <old_ssh_pid_1> <old_ssh_pid_2>

之后再次:

Terminal window
ss -lnt | grep -E '15721|17890'

发现没有输出。

这一步证明:

原来监听 15721 和 17890 的,确实是旧 SSH ReverseForward。

---

8. 重新建立 SSH 后,反向隧道恢复

Section titled “8. 重新建立 SSH 后,反向隧道恢复”

重新连接 VS Code Remote SSH 后再次检查:

Terminal window
ss -lnt | grep -E '15721|17890'

两个端口重新出现。

接着测试:

Terminal window
curl -v --max-time 10 http://127.0.0.1:15721/

这次立即返回:

HTTP/1.1 404 Not Found

这里的 404 不是坏消息。

因为访问的是 CCSwitch 根路径 /,它本来就不一定提供页面。

真正重要的是:

之前:connect 后超时
现在:
connect
立即收到 HTTP 响应

因此可以确认:

服务器
127.0.0.1:15721
SSH ReverseForward
Windows CCSwitch

链路已经恢复。

---

9. Windows 端确认 CCSwitch 正在监听 15721

Section titled “9. Windows 端确认 CCSwitch 正在监听 15721”

Windows 上执行:

Terminal window
netstat -ano | findstr ":15721"

可以看到:

127.0.0.1:15721 LISTENING

同时存在已经建立的连接。

因此:

Windows CCSwitch 监听 ✅
SSH ReverseForward ✅
服务器 15721 ✅

到这里,最初的端口故障已经解决。

---

10. 第二阶段故障:Claude Code 仍然 400 / 1210

Section titled “10. 第二阶段故障:Claude Code 仍然 400 / 1210”

虽然隧道已经恢复,但服务器上的 Claude Code VS Code 面板仍然报:

API Error: 400 [1210]
[API 调用参数有误,请检查文档。]

CCSwitch 请求记录中也能看到:

Provider:Zhipu GLM
状态:400
input tokens:0
output tokens:0

这说明请求已经经过:

Claude Code
15721
CCSwitch
智谱

并由智谱返回了参数错误。

因此第二阶段已经不能继续把问题归咎于 SSH。

---

11. 用最小 Anthropic Messages 请求验证基础 API

Section titled “11. 用最小 Anthropic Messages 请求验证基础 API”

服务器执行:

Terminal window
curl -i --max-time 30 \
http://127.0.0.1:15721/v1/messages \
-H "x-api-key: $ANTHROPIC_AUTH_TOKEN" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model":"claude-opus-5",
"max_tokens":32,
"messages":[
{
"role":"user",
"content":"你好"
}
]
}'

结果:

HTTP/1.1 200 OK

并返回:

{
"type": "message",
"role": "assistant",
"model": "glm-5.3-flash"
}

这一步非常关键。

它一次性证明:

15721 正常
CCSwitch 正常
智谱认证正常
Anthropic Messages 接口正常
claude-opus-5 模型映射正常
GLM-5.3-flash 正常

因此问题缩小为:

Claude Code 完整请求
手工最小 curl 请求

---

12. 一度怀疑 Opus 5 (1M),随后被实验排除

Section titled “12. 一度怀疑 Opus 5 (1M),随后被实验排除”

服务器 Claude Code UI 中显示:

Opus 5 (1M)
Max

而本地正常环境中显示的是:

glm-5.3-flash
Max

因此一度怀疑:

1M Context
thinking
beta header
特殊参数

可能触发智谱 1210

但后续实验表明:

Opus 5 (1M) 本身不是问题。

这个过程提醒我:

UI 上的差异
只能作为假设来源
不能直接作为根因结论

必须用实验验证。

---

服务器中同时存在:

anthropic.claude-code-2.1.263-linux-x64
anthropic.claude-code-2.1.267

最开始使用通配符:

Terminal window
~/.vscode-server/extensions/anthropic.claude-code-*/resources/native-binary/claude --version

返回:

2.1.263

但这个结果不能证明 VS Code 实际运行的是 2.1.263。

原因是 Shell 会把:

*

展开成多个路径,真正执行的可能只是展开后的第一个文件。

因此改用:

Terminal window
ps -ef | grep '[a]nthropic.claude-code'

直接查看 VS Code 当前进程。

结果明确显示:

/home/liangyc/.vscode-server/extensions/
anthropic.claude-code-2.1.267/
resources/native-binary/claude

所以:

VS Code 实际运行版本 = 2.1.267

---

14. 检查 VS Code Claude Code 的进程环境

Section titled “14. 检查 VS Code Claude Code 的进程环境”

进一步读取运行中 Claude Code 进程的环境:

Terminal window
PID=$(pgrep -n -f '/anthropic\.claude-code-2\.1\.267/resources/native-binary/claude')
tr '\0' '\n' < /proc/$PID/environ \
| grep -E '^(ANTHROPIC_|CLAUDE_CODE_|HTTP_PROXY|HTTPS_PROXY|ALL_PROXY|NO_PROXY)' \
| sed -E \
-e 's/^(ANTHROPIC_AUTH_TOKEN)=.*/\1=***HIDDEN***/' \
-e 's/^(ANTHROPIC_API_KEY)=.*/\1=***HIDDEN***/'

得到:

ANTHROPIC_AUTH_TOKEN=***HIDDEN***
NO_PROXY=localhost,127.0.0.1
HTTPS_PROXY=http://127.0.0.1:17890
HTTP_PROXY=http://127.0.0.1:17890
ALL_PROXY=http://127.0.0.1:17890
CLAUDE_CODE_ENABLE_TASKS=0
CLAUDE_CODE_ENTRYPOINT=claude-vscode
CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true

这里最有价值的是:

CLAUDE_CODE_ENTRYPOINT=claude-vscode

同时:

NO_PROXY=localhost,127.0.0.1

意味着访问:

127.0.0.1:15721

理论上不会经过 17890。

因此代理变量不是首要嫌疑。

---

下一步直接使用服务器上的同一个 Claude Code 2.1.267 二进制:

Terminal window
~/.vscode-server/extensions/anthropic.claude-code-2.1.267/resources/native-binary/claude \
-p "只回复你好" \
--output-format text \
--debug \
--debug-to-stderr

日志显示:

model=claude-opus-5[1m]
API REQUEST /v1/messages
Stream started - received first chunk

最后正常输出:

你好

这一步非常重要。

因为它证明:

Claude Code 2.1.267 二进制本身 ✅
Opus 5 (1M) ✅
Max thinking ✅
CCSwitch ✅
智谱 GLM ✅

也就是说:

2.1.267 不是在所有模式下都会失败

---

16. 关键 A/B 实验:只改变 CLAUDE_CODE_ENTRYPOINT

Section titled “16. 关键 A/B 实验:只改变 CLAUDE_CODE_ENTRYPOINT”

接下来做最关键的实验。

还是同一个 2.1.267 二进制,只加入:

Terminal window
CLAUDE_CODE_ENTRYPOINT=claude-vscode

完整命令:

Terminal window
CLAUDE_CODE_ENTRYPOINT=claude-vscode \
~/.vscode-server/extensions/anthropic.claude-code-2.1.267/resources/native-binary/claude \
-p "只回复你好" \
--output-format text \
--debug \
--debug-to-stderr

结果发生变化。

日志仍然显示:

model=claude-opus-5[1m]
API REQUEST /v1/messages

但随后立即:

400
code=1210
API 调用参数有误

此时实验条件可以写成:

条件版本ModelEntrypoint结果
A2.1.267claude-opus-5[1m]sdk-cli✅ 成功
B2.1.267claude-opus-5[1m]claude-vscode❌ 1210

这说明真正值得关注的变量变成了:

CLAUDE_CODE_ENTRYPOINT

而不是:

1M
模型映射
SSH
Token

---

17. VS Code 日志也验证了同样的失败路径

Section titled “17. VS Code 日志也验证了同样的失败路径”

VS Code Claude Code 日志中可以看到:

cc_entrypoint=claude-vscode

接着:

dispatching to firstParty model=claude-opus-5[1m]
API REQUEST /v1/messages

然后:

400
invalid_request_error
code=1210

并且程序尝试:

server-fallback
stripping and retrying

但重试仍然失败。

这和手工设置:

CLAUDE_CODE_ENTRYPOINT=claude-vscode

后的结果一致。

所以已经可以把故障范围缩到:

Claude Code 的 claude-vscode 调用路径

---

18. 最终版本对照:2.1.263 + claude-vscode

Section titled “18. 最终版本对照:2.1.263 + claude-vscode”

为了判断:

这是 claude-vscode 模式一直存在的问题
还是 2.1.267 的新回归

直接运行旧版 2.1.263:

Terminal window
CLAUDE_CODE_ENTRYPOINT=claude-vscode \
~/.vscode-server/extensions/anthropic.claude-code-2.1.263-linux-x64/resources/native-binary/claude \
-p "只回复你好" \
--output-format text \
--debug \
--debug-to-stderr

结果:

model=claude-opus-5[1m]
API REQUEST /v1/messages
Stream started - received first chunk

最终:

你好

因此得到决定性对照:

Claude CodeEntrypointModel结果
2.1.263claude-vscodeclaude-opus-5[1m]✅ 正常
2.1.267claude-vscodeclaude-opus-5[1m]❌ 400 / 1210
2.1.267sdk-cliclaude-opus-5[1m]✅ 正常

到这里,根因已经非常明确。

---

最终问题不是:

Opus 5 (1M)

不是:

Max thinking

不是:

CCSwitch 模型映射

不是:

智谱 Token

也不是:

15721 / 17890

最终根因可以描述为:

Claude Code 2.1.267 在 claude-vscode 调用路径下,与当前 CCSwitch → 智谱 GLM Anthropic 兼容接口之间出现了请求兼容回归,导致智谱返回 400 / 1210;同样环境下 2.1.263 正常。

目前已经通过控制变量实验复现:

2.1.263 + claude-vscode
→ 成功
2.1.267 + claude-vscode
→ 1210

---

20. 为什么一开始会误以为是端口问题

Section titled “20. 为什么一开始会误以为是端口问题”

这次故障实际上分成两个阶段。

第一阶段确实是:

旧 SSH 会话
占用 15721 / 17890
新 RemoteForward 绑定失败
反向隧道异常

这一阶段修复后:

15721 恢复
17890 恢复
CCSwitch 可达

但随后出现了第二阶段:

Claude Code VS Code 扩展使用 2.1.267
claude-vscode 请求路径
智谱 1210

因此从用户感知上看起来像:

“刚才只是修了端口,
为什么 Claude Code 突然坏了?”

实际上是:

端口故障
+
扩展版本/调用路径变化

两个问题连续出现。

这也是复杂系统排障中很常见的一种情况:

一个故障修好后,不代表当前看到的下一个错误仍然来自同一个根因。

---

21. 最终解决方案:远程 Claude Code 降级到 2.1.263

Section titled “21. 最终解决方案:远程 Claude Code 降级到 2.1.263”

在 VS Code Remote SSH 环境中:

Extensions
Claude Code
Install Another Version...
2.1.263

然后:

Ctrl + Shift + P
Developer: Reload Window

重新加载后检查:

Terminal window
ps -ef | grep '[a]nthropic.claude-code'

确认运行路径为:

anthropic.claude-code-2.1.263-linux-x64

然后新建 Claude Code 会话。

发送:

你好

最终恢复正常。

---

虽然服务器中同时存在:

2.1.263
2.1.267

但没有直接执行:

Terminal window
rm -rf ~/.vscode-server/extensions/anthropic.claude-code-2.1.267

原因是 VS Code 扩展目录不仅是简单文件夹。

手工删除可能造成:

扩展注册状态
版本状态
缓存
Extension Host

之间不一致。

更稳妥的方式是:

让 VS Code 自己执行版本切换

即:

Install Another Version...

---

为了避免:

2.1.263
自动更新
2.1.267
再次 1210

可以暂时关闭 Claude Code 扩展自动更新。

如果支持单扩展设置:

Claude Code
齿轮
Disable Auto Update

或者在 VS Code Settings 中搜索:

Extensions: Auto Update

临时关闭。

等后续版本确认与当前代理链兼容后再重新开启。

---

可以把这次过程整理成一张表。

检查项方法结果结论
磁盘df -h有剩余空间排除磁盘不足
inodedf -i使用率低排除 inode
远程端口ss -lnt15721/17890 存在只能说明监听存在
端口功能curl最初 timeout旧隧道失效
Remote SSH日志RemoteForward failed端口被旧 SSH 占用
旧 SSHps多个 sshd @notty找到旧会话
清理后端口ss -lnt端口消失确认旧 SSH 占用
重连后 15721curl /立即 404隧道恢复
CCSwitch API/v1/messages200API 链正常
模型映射返回 modelglm-5.3-flash映射正常
Claude 2.1.267 CLI-p成功二进制本身正常
2.1.267 vscode entrypoint设置 env1210成功复现
2.1.263 vscode entrypoint设置 env成功定位版本回归
VS Code 降级2.1.263正常回复故障解决

---

25. 这次排障中最重要的几个方法

Section titled “25. 这次排障中最重要的几个方法”

25.1 不要把“端口监听”当作“服务正常”

Section titled “25.1 不要把“端口监听”当作“服务正常””
LISTEN

只代表:

有人占用了这个端口

不代表:

请求一定能到目标服务

必须配合:

Terminal window
curl

做端到端验证。

最终定位依赖的就是这组实验:

相同版本
相同模型
相同 API
相同 CCSwitch
相同服务器
只改变:
CLAUDE_CODE_ENTRYPOINT

得到:

sdk-cli → 成功
claude-vscode → 失败

然后继续:

相同 entrypoint
相同模型
相同链路
只改变:
Claude Code Version

得到:

2.1.263 → 成功
2.1.267 → 失败

这比不断修改配置更有效。

25.3 一个错误修好后,要重新定义问题

Section titled “25.3 一个错误修好后,要重新定义问题”

第一次问题是:

为什么 15721 / 17890 不工作?

修复后就不应该继续问同一个问题。

新的问题变成:

为什么最小 API 已经 200,
但 VS Code Claude Code 还是 1210?

这一步问题定义的切换非常关键。

完整 VS Code 环境包含:

VS Code
Extension Host
Claude extension
Claude binary
settings
entrypoint
proxy
SSH
CCSwitch
provider

变量太多。

而:

Terminal window
claude -p "只回复你好"

把大量变量去掉。

随后:

Terminal window
CLAUDE_CODE_ENTRYPOINT=claude-vscode claude -p ...

又只增加一个变量。

最终成功复现。

这就是最小复现的价值。

---

排查过程中出现过多个合理但最后被实验排除的假设。

看起来:

本地正常:glm-5.3-flash
服务器异常:Opus 5 (1M)

确实很可疑。

但实验:

2.1.263
+
claude-vscode
+
claude-opus-5[1m]

可以成功。

所以:

Opus 5 (1M) ≠ 根因

运行参数中出现:

--max-thinking-tokens 31999

同样很容易怀疑 thinking。

但普通 2.1.267 CLI 在相同配置下可以成功。

因此也不能直接归因于 thinking。

CCSwitch 将:

claude-opus-5

映射为:

glm-5.3-flash

最小 /v1/messages 请求已经 200。

所以基础模型映射没有问题。

15721:

curl 根路径立即返回 HTTP

/v1/messages

200 OK

说明 SSH ReverseForward 已经正常。

后续 1210 属于新的问题。

---

排障截图中曾出现过:

ANTHROPIC_AUTH_TOKEN
API Key

明文认证信息。

排障时建议始终使用:

Terminal window
sed -E \
-e 's/^(ANTHROPIC_AUTH_TOKEN)=.*/\1=***HIDDEN***/' \
-e 's/^(ANTHROPIC_API_KEY)=.*/\1=***HIDDEN***/'

避免直接输出密钥。

如果密钥已经出现在:

截图
聊天
日志
共享文档

中,应该重新生成或轮换。

---

28. 后续再遇到类似问题时的快速排查顺序

Section titled “28. 后续再遇到类似问题时的快速排查顺序”

以后如果再次出现:

Claude Code
400 / 1210

可以按下面顺序检查。

Step 1
检查当前 Claude Code 版本
Step 2
检查 15721 / 17890 是否监听
Step 3
curl 127.0.0.1:15721
Step 4
curl /v1/messages 做最小 API 请求
Step 5
直接运行 Claude CLI
Step 6
设置 CLAUDE_CODE_ENTRYPOINT=claude-vscode 再运行
Step 7
如果 CLI 成功但 vscode entrypoint 失败
优先检查 Claude Code 版本兼容
Step 8
回退到已知可用版本

对应命令:

Terminal window
ps -ef | grep '[a]nthropic.claude-code'
ss -lnt | grep -E '15721|17890'
curl -v --max-time 10 http://127.0.0.1:15721/
~/.vscode-server/extensions/anthropic.claude-code-2.1.267/resources/native-binary/claude \
-p "只回复你好" \
--output-format text
CLAUDE_CODE_ENTRYPOINT=claude-vscode \
~/.vscode-server/extensions/anthropic.claude-code-2.1.267/resources/native-binary/claude \
-p "只回复你好" \
--output-format text

---

整次故障可以压缩成:

VS Code Remote SSH / Claude Code 异常
├─ 第一阶段:网络链路
│ ├─ 旧 SSH 会话仍存在
│ ├─ 15721 被旧 ReverseForward 占用
│ ├─ 17890 被旧 ReverseForward 占用
│ ├─ 新 SSH 无法重新绑定
│ └─ 清理旧 SSH + 重连
│ ↓
│ 网络恢复
└─ 第二阶段:Claude Code 400 / 1210
├─ 最小 curl /v1/messages → 200
├─ CCSwitch → GLM 映射 → 正常
├─ 2.1.267 sdk-cli → 正常
├─ 2.1.267 claude-vscode → 1210
├─ 2.1.263 claude-vscode → 正常
└─ 远程扩展降级至 2.1.263
故障解决

---

这次问题其实包含两个独立故障。

第一个是:

旧 SSH ReverseForward 会话占用端口

导致:

15721 / 17890

虽然处于监听状态,但实际隧道失效。

清理旧 SSH 会话并重新建立连接后,这一问题被解决。

第二个是:

Claude Code 2.1.267
+
claude-vscode entrypoint
+
CCSwitch → 智谱 GLM

组合下出现:

400 / 1210

通过 A/B 实验确认:

2.1.267 + sdk-cli
→ 正常
2.1.267 + claude-vscode
→ 1210
2.1.263 + claude-vscode
→ 正常

所以最终采用:

远程 Claude Code 扩展
2.1.267
降级
2.1.263

恢复正常。

这次排障最值得保留的方法不是某一个具体配置,而是:

先验证链路
再验证服务
再验证最小 API
再验证程序本体
最后用控制变量做版本 / 模式对照

---

端口故障修好以后,剩下的 1210 不是网络问题:
真正的根因是 Claude Code 2.1.267 在 claude-vscode 路径下
与当前 CCSwitch → 智谱 GLM 链路发生兼容回归;
降级远程 Claude Code 到 2.1.263 后恢复正常。