HiAPI
博客

教程

HiAPI 502 / 503 上游错误:原因与修复方法

2026年11月3日
HiAPI 502 / 503 上游错误:原因与修复方法

你调用 POST https://api.hiapi.ai/v1/tasks(或轮询 GET /v1/tasks/{id}),结果返回的不是通常的 200 加 taskId,而是 502 Bad Gateway 或 503 Service Unavailable。两者都是 5xx 响应,说明问题出在服务器或传输侧,而不是你的请求:你并没有发送错误参数、错误密钥或格式错误的负载。503 是 HiAPI 文档中记载的“平台暂时不可用”信号,告诉你应当重试;502 则是链路上某处产生的网关级响应。本指南说明如何确认这一点、如何在不重复劳动的前提下安全重试,以及如何将 502/503 与 504 超时和 TASK_FAILED 结果区分开来。

502 或 503 实际是什么样

你会看到 HTTP 状态行上出现以下之一,而不是正常的 200:

  • 503 Service Unavailable —— 这个是有文档记载的。HiAPI 的异步 API 文档将 503 列为 “平台暂时不可用;请稍后用指数退避重试”,对应的业务码是 TEMPORARILY_UNAVAILABLE(“生成服务暂时不可用。请稍后重试;如果问题持续存在,请联系支持。”)。HiAPI 的同步错误使用扁平 JSON 信封——文档中 400 的情况为 {"code": 400, "message": "...", "data": null, "error_code": "INVALID_REQUEST"}——因此 API 返回的 503 也应使用相同的信封,并带有 error_code: "TEMPORARILY_UNAVAILABLE"。
  • 502 Bad Gateway —— 这个不在 HiAPI 文档记载的状态码中。在标准 HTTP 中,502 表示网关或代理从其尝试访问的下一跳收到了无效或空响应。因此你收到的 502 是由链路上的网关产生的——可能是边缘/CDN 层、负载均衡器,或你自己网络中的代理——而不是 HiAPI 应用返回其通常的 JSON 信封。响应体通常是一个简短的 HTML 或纯文本网关页面,而这个非 JSON 的响应体本身就是一种信号:表明这是传输/网关状况,而不是带有固定、有文档记载负载的应用错误。

无论哪种情况,状态都是 5xx:问题在服务器或传输侧,而不是你的请求。这与 4xx 相反——400(参数错误)、401(密钥错误;HiAPI 返回嵌套的 {"error": {"code": "permission_denied", "type": "hiapi_error", "request_id": "..."}})或 402(余额不足)——这些都需要你改变自己这边的某些东西来修复。502/503 无法通过修改负载来修复。

常见原因(按可能性从高到低排列)

  1. 短暂的平台过载或维护窗口 → 503 TEMPORARILY_UNAVAILABLE。这是预期内的、有文档记载的情况。它会自行恢复,退避重试即可成功。
  2. 链路上某个网关或代理的瞬间抖动 → 502。边缘/CDN 层、负载均衡器或你自己网络中的代理短暂未能转发响应。同样是暂时性的。
  3. 流量突增触发了限制。 在高负载下,你可能反而看到 429 RATE_LIMITED(“请稍后重试;避免立即重新提交同一请求”)。如果状态是 429,解决办法是降低发送速率,而不是更用力地重试。
  4. 所请求的模型后端暂时不可用。 HiAPI 在任务级别将其记录为 MODEL_UNAVAILABLE(“请稍后重试,或切换模型”);服务该模型的平台级短暂故障也可能表现为 503。
  5. 不是密钥错误、请求体格式错误或余额不足。这些分别是 401 / 400 / 402,都不会表现为 502 或 503。

按顺序修复的方法

  1. 确认是 5xx,而不是 4xx。 先看状态码。502/503 属于服务器/传输侧;400、401、402、404、409、415、422 和 429 属于你这一侧。如果确实是 502/503,不要开始重写请求体——那只对 4xx 有帮助。
  2. 使用带抖动的指数退避重试。 文档明确要求对 503 使用指数退避。安全的客户端模式是起始约 1 秒,每次尝试翻倍(2 秒、4 秒、8 秒……),上限约 30–60 秒,并加入随机抖动,以免大量客户端同步重试。这些间隔是推荐的客户端模式,不是 HiAPI 发布的时间保证。
  3. 让提交具备幂等性。 在 POST /v1/tasks 上设置 Idempotency-Key 头(任意 UTF-8 字符串,最长 255 字节)。如果 502/503 让你不确定任务是否实际已创建,使用相同密钥重试是安全的:相同密钥 + 相同请求体将返回原始的 taskId,并带有响应头 Idempotent-Replay: true,而不会创建第二个任务或产生第二笔扣费。密钥按账户限定作用域,24 小时后过期。完整约定见 Unified Async API 文档。
  4. 不要在没有密钥的情况下盲目重新 POST。 如果你提交时没有 Idempotency-Key 并收到了 502/503,你可能已经创建了一个你看不到的任务——你没有可轮询的 taskId,因此朴素的重试有重复工作和重复扣费的风险。在任何规模的重试之前先加上密钥。
  5. 如果 502/503 发生在轮询期间,继续轮询即可。 GET /v1/tasks/{id} 返回的 5xx 不会改变任务状态。终态(success / fail)一旦到达就固定,永远不会互相转换,因此退避后再次轮询即可。或者,注册 callback.url,这样你会在终态时收到通知,而不必穿过暂时性的 5xx 进行轮询——投递是至少一次的,因此请按 taskId 去重。
  6. 将其与任务级失败区分开来。 如果你反而收到 HTTP 200 加 "status": "fail",那不是 502/503——任务已被接受、运行并失败。请按各自的方式处理 TASK_FAILED(“重试一次;如果问题持续存在,请联系支持”)或 TASK_TIMEOUT(“重试该任务”),而不是盲目进行网关重试。
  7. 如果持续存在,升级处理而不是猛击。 如果 502/503 在几分钟内经过多次退避重试后仍持续出现,应将其视为暂时性的平台事件,而不是可以蛮力解决的问题。停止激进重试,并在错误体包含 request_id 时携带它联系支持。你可以从 HiAPI 控制台确认自己的账户和连通性是否正常。

502 / 503 与 504 与 TASK_FAILED 的对比

这些很容易混淆,因为它们都意味着“没有干净地返回”,但需要不同的处理方式:

响应 HTTP 状态码 来源 任务是否扣费? 该怎么做
503 Service Unavailable 503(有文档记载) HiAPI 平台——暂时不可用或过载 无法从响应判断;任务可能已存在 使用退避和相同的 Idempotency-Key 重试
502 Bad Gateway 502(不在 HiAPI 文档中) 链路上的网关/代理(边缘、负载均衡器或你自己的代理) 无法从响应判断 使用退避进行幂等重试;如果只从你的网络出现,怀疑你这一侧有代理
504 Gateway Timeout 504(不在 HiAPI 文档中) 链路上停止等待的网关或代理(HiAPI 文档未列出 504) 无法从响应判断 与 502 相同;HiAPI 将自己的超时报告为 TASK_TIMEOUT
TASK_TIMEOUT 200 + "status": "fail" HiAPI——任务已运行但超出时间预算 否(预留金额已退还) 作为新请求重试该任务
TASK_FAILED 200 + "status": "fail" HiAPI——任务已被接受并运行,然后失败 否(预留金额已退还) 重试一次,然后读取 error.message
429 RATE_LIMITED 429 HiAPI——你发送得太快 无任务 退避;不要立即重新提交
400 / 401 / 402 4xx HiAPI——客户端侧(请求体/密钥/余额错误) 否 修复请求、密钥或余额;重试无济于事

一句话判断:502/503/504 是 HTTP 传输错误,不携带任何任务结果;而 TASK_FAILED / TASK_TIMEOUT 以 HTTP 200 加 "status": "fail" 和 error 对象的形式到达。前者意味着“你不知道请求是否送达”;后者是“请求已送达,任务已运行,并且失败了”。

最小验证示例

用一次干净的提交来证明你的密钥和连通性正常,并将 502/503 隔离为暂时性问题。使用一个你确定可用的模型 id(例如 gpt-image-2/text-to-image),并包含 Idempotency-Key,以便重试是安全的:

# A healthy submit returns 200 with a taskId. If this works but a specific
# call just 502/503'd, that 502/503 was transient — not your setup.
curl -sS -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: my-job-0001" \
  -d '{"model":"gpt-image-2/text-to-image","input":{"prompt":"a red bicycle on a white background"}}'

# Then poll the task you just created (swap in the returned id):
curl -sS https://api.hiapi.ai/v1/tasks/TASK_ID \
  -H "Authorization: Bearer $HIAPI_API_KEY"

如果提交本身返回 200 和一个 taskId,说明你的身份验证和网络路径正常,之前的 502/503 是暂时性的服务器/传输状况——重试失败的调用(复用相同的 Idempotency-Key 会返回原始任务,而不是重复任务)。如果提交反而返回 401 或 400,那是客户端侧问题,不是 502/503。

相关阅读

常见问题

502 或 503 是我的错吗? 不是。两者都是 5xx 响应,属于服务器侧或传输侧。你的 API 密钥和请求体不是触发因素——4xx(400/401/402)才是你造成且可以修复的那一类。对 502/503 的正确响应是幂等重试,而不是改代码。

在 HiAPI 上 502 和 503 有什么区别? 503 是 HiAPI 文档记载的“平台暂时不可用”代码(error_code: TEMPORARILY_UNAVAILABLE),来自平台本身。502不在 HiAPI 文档记载的状态码中;在标准 HTTP 中,它由链路上的网关或代理在上游返回无效响应时发出。两者都是暂时性的,都需要退避重试,但 502 也可能指向你自己网络中的代理。

503 与 504 有何不同? 503 表示服务当前暂时不可用或过载。504 Gateway Timeout 表示某处等待响应时间过长。HiAPI 文档未列出 504;如果你看到它,说明链路上某处的网关或代理放弃等待。HiAPI 自己的“耗时过长”状态是任务结果 TASK_TIMEOUT(HTTP 200 + "status": "fail")。参见上方的 504 指南。

如何将 502/503 与 TASK_FAILED 结果区分开? 看 HTTP 状态码。502/503 是没有任务负载的 HTTP 错误。TASK_FAILED 以 HTTP 200 加 "status": "fail" 和 error 对象的形式返回——任务已被接受并运行。对 502/503 使用退避重试;对 TASK_FAILED 重试一次,然后读取 error.message。

收到 502/503 后重试会扣我两次费或创建重复任务吗? 如果你在 POST /v1/tasks 上发送 Idempotency-Key 头,就不会。复用相同的密钥 + 请求体会返回原始的 taskId(Idempotent-Replay: true),而不会创建重复任务。而且失败的任务永不扣费——任务一旦到达失败终态,创建时预留的金额将全额退还。

应该退避多久,何时应该升级处理? 使用带抖动的指数退避(例如 1 秒、2 秒、4 秒、8 秒,设上限,并加入随机性)。如果 502/503 在几分钟内经过多次重试后仍持续返回,停止激进重试,并携带错误体中的 request_id 联系支持——持续的 5xx 通常意味着暂时性的平台事件,而不是更快的重试循环能解决的问题。

看到 502/503 时我应该修改请求负载吗? 不用。502/503 不是验证错误,因此修改参数无济于事,还可能掩盖真正的暂时性原因。保持请求不变,如果尚未添加则加上 Idempotency-Key,然后使用退避重试。

立即开始构建持久 AI 产物

获取 API 密钥,通过一个基于任务(task)的 API 调用图像、视频和音频模型。

阅读 API 文档