Gateway 错误码与处理方式
本页以 Halro 8f185de7674c 的公开 Gateway 数据面和 Run Governance 错误构造点为基线,不包含
Admin 控制面的表单错误。OpenAI 形状端点和 Run Governance 可以按 error.code 分支;Anthropic
门面没有 error.code,应按 HTTP 状态和 error.type 处理。两种门面都应记录 Request ID;
message 是面向人的脱敏说明,不是稳定协议字段。
同一个 code 在不同阶段可能对应不同 HTTP 状态,表中会全部列出。状态码相同也不代表处理方式相同。
请求、身份与能力
Section titled “请求、身份与能力”| code | HTTP | 含义与处理 |
|---|---|---|
invalid_api_key | 401 | Key 缺失、格式错误、无效或已吊销;修复凭据,不重试原值 |
gateway_key_scope_denied | 403 | Key 缺少所需 Scope;由管理员签发最小权限 Key |
model_not_allowed | 403 | Project 没有授权该公开别名 |
source_not_allowed | 403 | 来源地址不在 Project 允许范围 |
model_not_found | 404 | 公开 Route 别名不存在 |
invalid_request_error | 400 | 请求体、字段组合或端点语义无效;修改请求后再发 |
invalid_forwarded_for | 400 | 可信代理链中的 X-Forwarded-For 无法安全解析;修复代理配置 |
request_too_large | 400、413 | 400 可来自单个 multipart 字段超限;413 表示整体请求超过实例或 Project 上限 |
unsupported_feature | 400、501 | Route/Profile 无法表达请求;501 仅表示实例未提供延迟执行能力 |
streaming_unsupported | 500 | 当前 HTTP Writer 无法安全提供流式响应;保留 Request ID 并通知管理员 |
endpoint_not_implemented | 404 | 路径不在 Halro 支持面;按兼容性文档选择端点 |
method_not_allowed | 405 | 已知路径不接受当前 HTTP 方法 |
route_required | 400 | File 创建缺少 Halro-Route 请求头 |
ambiguous_resource_route | 409 | 资源型 Route 没有唯一 eligible Deployment |
token_limit_exceeded | 400 | 单请求输入或输出 Token 上限被拒绝 |
native_redaction_incompatible | 400 | 原生协议正文若脱敏会改变其语义,因而失败关闭 |
streaming_redaction_incompatible | 400 | 当前流式请求与配置的脱敏方式不能安全组合 |
幂等与资源状态
Section titled “幂等与资源状态”| code | HTTP | 含义与处理 |
|---|---|---|
invalid_idempotency_key | 400 | Key 为空、格式或长度不符合要求 |
idempotency_conflict | 409 | 同一个 Key 被用于不同正文或归因;不要换 Key 掩盖冲突 |
idempotency_in_progress | 409 | 同一创建操作正在执行或结果不明确;已有资源 ID 才查询,否则用相同 Key、正文和归因有界重试 |
resource_not_found | 404 | 资源不存在、不属于当前 Project 或已经删除 |
resource_owner_unavailable | 409 | 创建资源时绑定的目标当前不能继续执行该操作 |
resource_store_unavailable | 503 | 本地资源状态无法安全读写;有界重试并通知管理员 |
provider_cancel_unsupported | 409 | 上游没有可证明的取消操作;不能当作任务已经停止 |
response_not_found | 404 | 延迟 Response 不存在、不属于当前 Project 或已过保留期 |
deferred_response_in_flight | 409 | Response 仍在运行,当前操作要求先进入终态 |
deferred_response_not_cancellable | 409 | 当前状态不能取消 |
deferred_response_route_unavailable | 409 | 延迟任务绑定的原目标无法恢复 |
deferred_response_unreadable | 500 | 已保存的延迟结果无法安全读取;停止重复操作并通知管理员 |
预算、价格与限流
Section titled “预算、价格与限流”| code | HTTP | 含义与处理 |
|---|---|---|
budget_exceeded | 403 | Project 日预算不足;请求未到 Provider,盲重试无效 |
run_budget_exceeded | 403 | Run 生命周期余额不足;调整请求或关闭 Run |
price_unavailable | 409、503 | 409 表示请求需要已知价格或候选价格冲突;503 表示有效价格读取失败。都不能填成零成本 |
token_guard_blocked | 403 | 固定阈值或 temporary block;按错误详情调整请求/策略或等待 TTL |
rate_limit_exceeded | 429 | 来源或 Project RPM;有 Retry-After 时按其有界退避 |
token_rate_limit_exceeded | 429 | Project TPM 已满 |
concurrency_limit_exceeded | 429 | Project 并发已满 |
deployment_concurrency_limit_exceeded | 429 | Deployment 并发已满 |
provider_concurrency_limit_exceeded | 429 | 所有 eligible Provider 目标都在并发上限 |
Run Governance
Section titled “Run Governance”| code | HTTP | 含义与处理 |
|---|---|---|
invalid_run_id | 400 | X-Halro-Run-ID 格式错误 |
run_governance_disabled | 403 | Project 未启用运行治理 |
run_not_found | 404 | Run 不存在或不属于当前 Project |
run_not_active | 409 | Run 已关闭或过期 |
run_governance_unavailable | 503 | 无法验证治理权威状态;Halro 失败关闭,交给管理员处理 |
unsupported_content_type | 415 | 治理写入端点要求 application/json |
invalid_request | 400 | 治理请求体无法解码或不符合端点结构 |
invalid_outcome_definitions | 400 | Outcome Definition 数量、唯一性、格式或启用状态不合法 |
work_unit_not_found | 404 | Work Unit 或其中的 Definition 不存在,或不属于当前 Project |
invalid_outcome | 400 | Outcome 没有匹配冻结的 Definition,或值不合法 |
outcome_revision_conflict | 409 | supersedes_outcome_id 不是当前修订;先读取最新 Outcome |
outcome_write_closed | 409 | Outcome 的写入窗口已经关闭 |
governance_unavailable | 503 | Outcome 治理状态无法安全读取或写入,失败关闭 |
invalid_run | 400 | Run 预算或 TTL 超出 Project 限制 |
invalid_close_reason | 400 | Close reason 长度不在 1–64 字符范围 |
governance_rate_limited | 429 | 治理 API 的每 Key 请求速率超限 |
governance_resource_limit | 429 | Project 的 Run Governance 资源数量达到上限 |
work_unit_closed | 409 | Work Unit 已关闭,不能继续执行该写操作 |
内容策略与 Provider
Section titled “内容策略与 Provider”| code | HTTP | 含义与处理 |
|---|---|---|
content_rejected | 400 | 文件或音频未通过内容策略 |
sensitive_data_detected | 400、502 | 400 为入站拒绝;502 为上游结果或资源结果无法安全交付 |
sensitive_output_detected | 422 | Provider 已返回内容,但输出脱敏策略拒绝交付;调用可能已经计费 |
policy_error | 503 | Policy 状态无法安全读取或执行 |
redaction_policy_error | 500 | 脱敏处理发生内部错误;停止自动重试并通知管理员 |
provider_authentication_error | 502 | 上游拒绝 Halro 的 Provider 凭据;由管理员修复 Credential |
provider_rate_limit | 429 | 上游限流;只在上游给出可解析值时才有 Retry-After |
provider_timeout | 504 | 上游结果不明确,可能已经计费;不要把重发当作免费重试 |
provider_error | 502 | 上游或响应转换失败;结合 Request ID 查看 Attempt,费用结果可能不明确 |
provider_unavailable | 503 | 当前没有健康 eligible Deployment;有界退避并检查 Route 状态 |
账务、配置和内部状态
Section titled “账务、配置和内部状态”| code | HTTP | 含义与处理 |
|---|---|---|
accounting_error | 503 | 账务操作失败,Halro 拒绝继续调用 Provider |
accounting_unavailable | 503 | 无法安全完成预留或结算;停止无界重试并通知管理员 |
configuration_stale | 503 | 管理变更已持久化但新配置未安全激活;数据面失败关闭 |
internal_error | 500 | 网关内部失败;保留 Request ID,由管理员检查日志、状态和完整性 |
客户端处理顺序
Section titled “客户端处理顺序”- 保存 Request ID、HTTP 状态,以及该门面存在的
error.code或error.type;不要记录 Key 或请求正文。 - 400、401、403、404 通常先修请求、权限或配置;未经改变不要重发。
- 409 先读取资源或当前状态。若
idempotency_in_progress没有返回资源 ID,以相同 Key、正文和归因 做有界退避重试;持续冲突时保留 Key、停止创建并交给管理员,不要换 Key 绕过状态。 - 429 只在有
Retry-After时按该值退避;否则使用有抖动的应用级退避和最大次数。 - 502、504 或连接中断可能对应已经发生的 Provider Attempt 和费用;在 Usage 中核对后再决定重发。
- 账务、治理、策略或
configuration_stale的 503 表示安全状态不可确认,应交给管理员恢复;不要用 无限重试制造第二次故障。
Anthropic 门面的错误类型
Section titled “Anthropic 门面的错误类型”/v1/messages 与 /v1/messages/count_tokens 返回 Anthropic 形状:顶层为 type、error 和
request_id,其中 error 只有 type 与 message,没有 code。Halro 按最终 HTTP 状态映射:
| HTTP | error.type |
|---|---|
| 401 | authentication_error |
| 403 | permission_error |
| 404 | not_found_error |
| 413 | request_too_large |
| 429 | rate_limit_error |
| 500、502、504 | api_error |
| 503 | overloaded_error |
| 上游实际返回 529 | overloaded_error |
| 其他状态,包括 400、409、415、501 | invalid_request_error |
因此 Anthropic 客户端不能从本页前述 code 表直接读取响应字段;需要把 HTTP 与 error.type
映射到同一套重试和人工处置策略。
错误信封、Request ID 和 Scope 见认证、请求头与错误,生产排障见 日常巡检、完整性检查与告警。