跳到主要内容

错误

任何 2xx 之外的响应都带一个 JSON 体。请根据 code 分支,绝不要根据 message——消息是写给人看的,随时可能改措辞。

外层结构​

{
"detail": {
"code": "INSUFFICIENT_BALANCE",
"message": "Deploying needs about 1h of credit up front for this and the organization's other instances",
"balance_micro": 0,
"required_micro": 2305000
}
}
键类型含义
detail.code字符串稳定、全大写,可以放心用来分支
detail.message字符串一行给人看的解释
额外的键视情况而定针对这次具体失败的上下文

有两类失败用的是另一种结构。框架抛出的请求校验错误会在 detail 下放一个列表,每个有问题的字段一条:

{"detail": [{"type": "greater_than_equal", "loc": ["body", "disk_gb"], "msg": "Input should be greater than or equal to 10"}]}

而意料之外的服务端故障会在那里放一个纯字符串,比如 {"detail": "Internal Server Error"}。如果你在写客户端库,这三种形态都要处理。

HTTP 状态码​

状态码含义
200请求成功
201创建出了某个东西——一个实例、一份模板副本、一个 API 密钥
204成功但没有响应体:吊销密钥、删除 SSH 密钥
400请求本身有毛病,比如 X-Org-Id 不是一个 id
401bearer 令牌缺失、无效、过期、已吊销,或者把 API 密钥用在了账户端点上
402组织的余额不够这次操作
403你通过了认证但没有权限:仅限管理员的操作、组织不对,或者对象不可修改
404不存在,或者你的组织看不到——这两者是故意做成无法区分的
409状态冲突:报价被人抢走、实例处在错误的状态、名称已被占用、实例数已达上限
410已失效:邀请已被使用、已过期或已撤销
413请求体超过了端点接受的大小
422取值不对:字段超出范围、磁盘比机器还大、枚举值未知
429请求过于频繁:等 Retry-After 给出的秒数
503暂时不可用:主机暂时无法完成的启动,或暂时无法进行的登录验证。稍后重试

租用方真正会撞上的​

情形状态码代码该怎么办
余额不够组织在这个实例运行后跑一小时(这个实例的 GPU 加磁盘,加上运行中、启动中或正在创建的实例的 GPU 加磁盘,以及已停止实例的磁盘)时部署或启动,余额为正也一样402INSUFFICIENT_BALANCE由管理员在控制台里添加余额。响应体里带着 balance_micro 和 required_micro。API 密钥不能充值。
组织里尚未销毁的实例已有 25 个——stopped 和 error 的也算409INSTANCE_LIMIT_REACHED响应体中带有 limit。先销毁不再需要的实例,包括处于 error 的,再部署。
在你的列表调用和部署之间,或者就在你的部署预留的那一刻,报价被人租走了409OFFER_UNAVAILABLE从你筛出的列表里取下一份报价重试。不要用同一个 offer_id 重试。什么都没有被创建。
这台机器被安排下线的时间,比启动一个实例所需的时间还早409MACHINE_IN_MAINTENANCE响应体中带有 next_maintenance。换台机器部署,或等这段窗口过去。这不是容量问题——机器上还有空闲 GPU——所以窗口结束后用同一份报价重试是可以的。
disk_gb 不在 10–20000 之内422校验错误列表发一个落在范围内的值
disk_gb 比主机的磁盘还大422DISK_TOO_LARGE响应体里带着 max_disk_gb。按不超过它的值重试,或者换一台更大的机器。
仅限管理员的操作,或者用 API 密钥去做任何管理员操作403ADMIN_REQUIRED改用属于管理员的会话令牌。充值订单、发票信息、邀请和成员管理永远不对密钥开放。见角色与权限。
吊销一个未知的、已经吊销的,或属于别的组织的密钥404API_KEY_NOT_FOUND重新调 GET /v1/api-keys 列一遍,用当前的 id
从一个不允许的状态去停止、启动或销毁409INVALID_STATE先读一下 status。消息里会点明当前那个状态,例如 Cannot start an instance while it is running。
在不支持虚拟机的机器上用 vm 模板422OFFER_NOT_VM_CAPABLE筛出 vm_capable 为 true 的报价
模板被标记为即将推出(镜像还没有发布)422TEMPLATE_COMING_SOON换一个模板。GET /v1/templates 会列出这种模板,但它们无法部署。
模板固定了较旧的 CUDA 栈(cuda_max),而机器的 CUDA 版本更高422TEMPLATE_CUDA_TOO_NEW换一台 cuda_version 不超过模板上限的机器,或换一个模板
模板声明了 x86_64 以外的架构422TEMPLATE_ARCH_UNSUPPORTEDSuperheat 的机器都是 x86_64。改用 x86_64 镜像的模板。
别的组织的模板,从带凭据的私有镜像仓库拉取422TEMPLATE_REQUIRES_OWNER只有拥有它的组织能部署。把它复制到你的组织并填入你自己的仓库凭据(前提是你有权拉取那个镜像)。什么都没有被创建。
报价所在的机器没有在机群控制平面登记409OFFER_NOT_PINNABLE列表不会显示这种报价,一般是拿着旧的 offer_id。重新列出报价另选一份。什么都没有被创建。
启动一个 GPU 被释放过的实例,而原来那几块正被别人使用,或者在那台机器上已停止服务409CAPACITY_UNAVAILABLE实例仍然是 stopped,磁盘完好,但启动成功之前拿不到磁盘上的数据。稍后重试,这期间照样收存储费。一直不成功的话,唯一的出路是销毁实例后重新部署——销毁会把磁盘连同数据一起删除。
启动一个主机接不住的实例409, 503HOST_UNREACHABLE, START_REFUSED, START_UNAVAILABLE实例仍然是 stopped。稍后重试——START_UNAVAILABLE 可以很快重试。消息说主机已不再持有工作负载的 START_REFUSED 不会成功:销毁后重新部署。
同一个调用方的请求太多429RATE_LIMITED等 Retry-After 响应头里的秒数(响应体里也有 retry_after_s),再重试。
请求体超过大小上限413PAYLOAD_TOO_LARGE响应体里带着 limit_bytes。发小一点:大多数端点 1 MiB,模板 4 MiB。
凭据不能附加的 ssh_key_id:不是你自己的,或者——用 team 密钥时——不是现任成员的404SSH_KEY_NOT_FOUND用会话令牌调 GET /v1/ssh-keys 列一遍,从中挑一个 id
你的组织看不到的实例、报价或模板404INSTANCE_NOT_FOUND, OFFER_NOT_FOUND, TEMPLATE_NOT_FOUND检查你发的 X-Org-Id,以及那个对象是否还在

所有部署错误都在保留任何东西之前返回:被拒绝的部署不会留下实例。

认证和组织相关的失败——TOKEN_INVALID、TOKEN_EXPIRED、NOT_A_MEMBER、ORG_MISMATCH、INVALID_ORG_ID——在身份认证里讲。完整的代码清单见错误代码。

重试​

响应要重试吗?
402不。在余额到账之前,什么都不会变。
409 OFFER_UNAVAILABLE要,换一份报价。
409 MACHINE_IN_MAINTENANCE要,换一台机器;或者等过了 next_maintenance 再用同一台。
409 INSTANCE_LIMIT_REACHED只有在销毁了至少一个实例之后才行。
409 OFFER_NOT_PINNABLE要,换一份报价——同一份永远不会成功。
409 INVALID_STATE只有在重新读取实例、确认这次状态转换现在合法之后才行——allowed_actions 会告诉你哪些合法。
409 HOST_UNREACHABLE、START_REFUSED、CAPACITY_UNAVAILABLE过一会儿再试,并逐步拉长间隔。这期间实例一直是 stopped。
429 RATE_LIMITED要,等 Retry-After 秒之后。
503要,稍等片刻之后。
422不。先把请求改对。遇到 INVALID_CURSOR 时,去掉游标从头列出。
401 TOKEN_EXPIRED要,用新的会话令牌重试一次。shk_ 密钥不会过期,所以密钥上出现 401 就意味着它被吊销了。

POST /v1/instances 不接受幂等键,所以一旦超时,你就不知道这次租用到底成没成。**去查,而不是去重试:**调 GET /v1/instances,按你的 label 比对。

用同一个 offer_id 重试不安全。一份报价是一种规格,不是一个独占名额 —— 只要那台机器还有空余 GPU,同一份报价就会再被满足一次,你会拿到第二个实例、单独计费,而你本来只想部署一次。只有当那台机器的份额已经用光时它才会返回 409,而那恰恰是你本来就不会被重复扣费的情况。