> 原始 Markdown 孪生体（构建期从源 Markdown 生成）。渲染页：https://docs.gatellm.io/zh-CN/usecases/troubleshooting · 文档索引：https://docs.gatellm.io/zh-CN/llms.txt


# 从症状出发排障

排障的第一步永远是拿到 `z-request-id`——它是贯穿客户端、网关、上游、日志的唯一线索。

## 先拿到 z-request-id

每个请求的响应头里有 `z-request-id`（格式 `<iso8601>-<uuid4>`）。客户端报错时，让客户端把响应里的这个头给你。顺手把 `z-gateway`（格式 `<brand>/<version>`，如 `Protoflux/0.2.1`）也拿回来——先确认版本再排查，避免对着一个旧镜像已经修过（或尚未包含）的症状白费功夫。

::: tip 拿不到响应头时
客户端在收到响应前就失败了（连接被拒、TLS 失败）时没有 `z-request-id`——这种是网关没收到请求或收到前就断，从网关侧日志查不到，先查网络层（端口、防火墙、反代）。
:::

进控制台 → 日志页，在搜索框粘上这个 ID 即可定位。日志详情含完整请求/响应生命周期，见 [导出账单 Excel 与日志排查](/zh-CN/howto/billing-export-and-logs.md) 的「实战：定位客户端问题」。

## 客户端报 401 / 403

| 状态码 | error_type 常见值 | 含义 | 处理 |
|--------|------------------|------|------|
| 401 | authentication_error | 没带访问密钥或密钥无效/被禁用 | 检查 `Authorization: Bearer` 后跟的是你签发的访问密钥（不是上游 `sk-...`）；密钥是否被禁用 |
| 403 | model_access_denied | 密钥所在密钥组的 `models` 列表没含该模型 | 回密钥组把模型加进去（或 `*`） |
| 403 | model_access_denied | 密钥组的 `load_balancers` 没含该 LB | 回密钥组「负载均衡器」子页签勾选（`*` 不含 LB） |
| 403 | ip_banned | IP 被封禁（连续登录失败触发） | 等几分钟（默认 300 秒）自动解封 |

403 的 LB 维度是最常见的配错点，见 [多租户隔离](/zh-CN/usecases/multi-tenant-isolation.md#lb-is-auth-unit)。

## 客户端报 404

- `model_not_found`：模型名拼错，或该模型被设了 `hide_name`（只能用别名访问）。见 [上游与模型字段](/zh-CN/reference/upstreams-models-fields.md) 的「隐藏主名」。
- 别名 vs 规范名：密钥组 `models` 只匹配规范名，不解析别名。
- 完整 404 错误码见 [错误码速查](/zh-CN/reference/error-codes.md)；Claude Code 场景的 404 模型名对齐见 [Claude Code 经网关接入 → 常见问题](/zh-CN/quickstart/claude-code-via-gateway.md#faq)。

## 客户端报 400

| error_type | 成因 | 处理 |
|--------|------|------|
| `bad_request` | 请求 JSON 解析失败 / 字段语义校验失败 | 检查请求体 JSON 与必填字段 |
| `unsupported_feature` | 该「客户端协议 → 上游协议」组合没有翻译器 | 查 [协议互通矩阵](/zh-CN/reference/protocol-matrix.md) 换协议 |
| `invalid_request_error`（Anthropic 客户端） | 对话历史里 `tool_use` id 重复 | 去重 `tool_use` id，见 [错误码速查](/zh-CN/reference/error-codes.md) |

**带图片的请求被上游 400 拒收**（文本模型收到了带图请求）：给模型加一条 `switch-route` 规则把带图请求改投视觉模型，见 [增强模型能力](/zh-CN/usecases/model-enhancement.md) 场景一与 [把含图片的请求路由到视觉模型](/zh-CN/howto/route-image-requests-to-vision-model.md)。

## 客户端报 429

429 有多种来源，体格式与是否带头都不同，先分清是哪种（完整见 [错误码速查 → 429 的来源](/zh-CN/reference/error-codes.md#source-of-429)）：

| 来源 | 体 / 头特征 | 处理 |
|------|------------|------|
| 每访问密钥限流 | JSON 体，**带** `Retry-After` 头 | 该密钥请求过密；分流密钥或降频，必要时在控制台调高密钥/组的 `rate_limit`（RPM/TPM） |
| 每 IP 限流 | JSON 体，无 `Retry-After` | 同一 IP 请求过多；调 `IP_RATE_LIMIT_RPM` |
| 上游限流 | JSON 体，**带** `Retry-After` 头 | 上游本身限流；按 `Retry-After` 退避重试，或加 key / 加上游分摊 |
| 过载准入（排队深度 / 连接预算 / 内存门） | JSON 体，**带** `Retry-After` 头 | 网关本身健康但在途过载；按 `Retry-After` 退避重试。持续出现说明容量不足——扩容，或核对 [内存准入与溢写](/zh-CN/reference/configuration.md#memory-admission-spill)、[监听与请求限制](/zh-CN/reference/configuration.md#listen-and-request-limits) 各预算配置 |

> 限流各层的配置见 [审计与安全配置 → 限流](/zh-CN/reference/audit-and-security-config.md#rate-limit)；内存门触发的 429 与内存水位另见下方「网关内存异常升高」。

## 客户端报 502 / 503

| 状态码 | 来源 | 处理 |
|--------|------|------|
| 502 bad_gateway | 上游不通或返回非预期 | 检查上游 `base_url`、API key、上游可达性 |
| 503 | 所有节点不可用（LB 重试预算耗尽）/ 网关排空（drain） | LB 场景检查每个 entry 的上游；排空是正常下线 |
| 503 upstream_saturated | 候选上游全部饱和（坏死链接预算满） | 带 `Retry-After`，按其退避重试；打开控制台 设置 → 系统 的「上游健康」块定位挂死的上游，检查其连通性 |
| 504 outbound_deadline_exceeded | 出站尝试链总时限耗尽 | 上游长时间无首响应；检查该上游连通性与超时配置 |

503 持续不停 = 所有节点都挂，检查每个上游。Bedrock 场景注意填的是 Bedrock API key 不是 IAM key，见 [接入 AWS Bedrock](/zh-CN/quickstart/aws-bedrock.md)。

## 请求很慢或超时

- 客户端超时但上游正常：检查 `UPSTREAM_SEND_TIMEOUT_SECS`（发请求体+等响应头，默认 180）/ `UPSTREAM_READ_TIMEOUT_SECS`（单块读，默认 600）。整个上游生命周期还有一道 3600 秒的硬上限（固定，不通过环境变量开放）。见 [环境变量配置参考](/zh-CN/reference/configuration.md)。
- 上游本身就慢（推理模型长思考）：调大 `UPSTREAM_READ_TIMEOUT_SECS`，它每块重置。
- 跨境上游僵尸连接：跨境建议调短反代/上游侧的 keepalive；该 TCP keepalive 参数未通过环境变量开放，有需要请联系支持。

## 流式中途断掉

- 首块发出后上游断：不换节点，记录 `body_incomplete`，已收部分返回客户端。
- 网关侧超时：`STREAMING_KEEPALIVE_SECONDS`（默认 15）发 SSE `:keep-alive`，需短于反代空闲超时（Nginx 默认 60）。反代超时太短会切断长流。
- 流式时长或空闲超上限：`MAX_STREAM_DURATION_SECS`（默认 3600）是单流总时长上限，`STREAM_IDLE_TIMEOUT_SECS`（默认 600）是两块间空闲上限，超过即断流。

以上流式相关环境变量（`STREAMING_KEEPALIVE_SECONDS` / `MAX_STREAM_DURATION_SECS` / `STREAM_IDLE_TIMEOUT_SECS`）见 [环境变量配置参考 → 流式](/zh-CN/reference/configuration.md#streaming)。

## 网关内存异常升高

- 大 body 场景用了 after 槽脚本做纯路由决策：改用 `switch-route` 规则。见 [脚本性能与内存](/zh-CN/practices/script-performance.md) 的反模式。
- `max_request_size_mb` / `max_response_body_mb` 设得过大：多模态大对话占内存。
- 内存门（memory gate）触发 429：调 `memory_soft_limit_mb` 或检查是否有异常大的突发流量。

## 还定位不了怎么办

1. 拿 `z-request-id` 进日志页看完整请求/响应/错误详情。
2. 看错误码对照 [错误码速查](/zh-CN/reference/error-codes.md)。
3. 实时观察用日志页 Live 开关（SSE 流），见 [日志查看器](/zh-CN/console/logs-viewer.md)。
4. 多实例时 Live 汇聚所有实例日志。

## 常见问题

**Q：日志里找不到这个 z-request-id？**
可能请求没到网关（网络层断），或在 401 早期失败阶段（未持久化）。检查客户端是否真连到了网关端口。

**Q：错误体格式是什么样的？**
三种格式（取决于客户端协议与错误阶段），见 [错误码速查](/zh-CN/reference/error-codes.md)。

**下一步**：[错误码速查](/zh-CN/reference/error-codes.md) 看完整错误码；[日志查看器](/zh-CN/console/logs-viewer.md) 看 UI；[脚本性能与内存](/zh-CN/practices/script-performance.md) 看内存反模式。
