跳到主要内容

错误代码

当某个操作被拒绝时,原因会以一个简短的机器可读代码返回。控制台会用你的控制台语言把其中大部分渲染成 toast 提示;它还不认识的代码会显示 API 自己的消息,那是英文的。API 则以 JSON 返回。

{
"detail": {
"code": "OFFER_UNAVAILABLE",
"message": "This offer is no longer available"
}
}

少数代码会在 code 和 message 之外附带额外字段——DISK_TOO_LARGE 会返回 max_disk_gb,MACHINE_DISK_EXHAUSTED 会返回 available_disk_gb,客户端据此可以直接把滑块收到上限以内并重试,不必再发一次请求。

这两个值不能互换,夹错了会无限循环。max_disk_gb 是机器的总磁盘容量;available_disk_gb 是扣掉同机其他租户以及 50 GB 主机预留之后剩下的。所以一台机器可以通过 DISK_TOO_LARGE 而仍然返回 MACHINE_DISK_EXHAUSTED——即使是一台空机器,因为那份预留永远不出售。拿到 available_disk_gb 时请按它来夹。

身份验证与组织范围​

状态码代码成因处理方式
401TOKEN_INVALID没有 Authorization 头、令牌格式错误、API 密钥未知或已吊销,或者把 API 密钥发到了账户级接口发送有效的 bearer 令牌。/v1/me 和 /v1/ssh-keys 这类账户级接口需要已登录的会话,而不是 shk_ 密钥
401TOKEN_EXPIRED会话令牌已过期重新登录。无人值守的脚本请改用 API 密钥
403NOT_A_MEMBERX-Org-Id 指向了一个你不属于的组织去掉该请求头以使用你的个人组织,或者请管理员发送邀请
403ORG_MISMATCHX-Org-Id 与该 API 密钥所属的组织不一致移除该请求头,或改用属于该组织的密钥
403ADMIN_REQUIRED以成员身份或使用 API 密钥执行了仅管理员可做的操作——付款、邀请、成员管理、团队 API 密钥请管理员操作,或在已登录的管理员会话中重新执行
400INVALID_ORG_IDX-Org-Id 不是合法的 id从 GET /v1/orgs 中复制 id
403MFA_REQUIRED你的账号已注册两步验证,而这个会话令牌还没有完成第二步重新登录,并输入身份验证器应用里的验证码。控制台会自己把你带到这一步。API 密钥不受影响
503AUTH_UNAVAILABLEAPI 此刻无法校验你的登录——签名密钥或两步验证状态读不到稍等片刻再试。你的会话仍然有效

每个请求都有的限制​

状态码代码成因处理方式
429RATE_LIMITED同一调用方的请求过多——一个已登录的用户、一个 API 密钥,或者对匿名请求而言,一个 IP 地址。每个 /v1 请求都计入每分钟 600 次的额度;POST、PUT、PATCH 和 DELETE 还同时计入每分钟 60 次的额度。某个 IP 地址的请求每分钟被以未认证拒绝超过 60 次时,该地址上任何尚未成功用过的凭据也会收到这个错误等待 Retry-After 响应头里的秒数(响应体里也有 retry_after_s),然后重试。/v1/health 从不受限
413PAYLOAD_TOO_LARGE请求体超出了该接口接受的大小:大多数接口为 1 MiB,/v1/templates 下为 4 MiB。响应里带有 limit_bytes发送更小的请求体。模板的 readme 和启动脚本各有自己的上限,远在这之内

部署​

状态码代码成因处理方式
402INSUFFICIENT_BALANCE部署或启动实例时,你的余额不足以覆盖这个实例运行时组织一小时的消耗 —— 它的 GPU 和磁盘,加上运行中、启动中或创建中实例的 GPU 和磁盘,以及已停止实例的磁盘。余额大于零是不够的。响应里带有 balance_micro 和 required_micro充值余额。只有管理员才能充值
409OFFER_UNAVAILABLE从你打开报价到你点击部署之间,该形态的最后一份空闲已被拿走——或者在你的部署预留期间被另一个部署拿走返回市场另选一份报价。卡片上的数字只是一个快照,真正决定的是部署本身
404OFFER_NOT_FOUND传给 GET /v1/offers/{id} 的 id 不存在,或该报价已从目录中撤下。针对未知报价的部署返回的则是 OFFER_UNAVAILABLE重新列出报价,使用当前有效的 id
422DISK_TOO_LARGE请求的 disk_gb 超过了该机器的总容量。响应中包含 max_disk_gb请求不超过 max_disk_gb 的容量,或改选磁盘更大的机器
409MACHINE_IN_MAINTENANCE这台机器已被安排下线,时间太近,无法在上面启动实例。响应中包含 next_maintenance改选别的机器,或等这段维护窗口过去再来。更远的窗口不会阻止部署——它会显示在报价上
409MACHINE_DISK_EXHAUSTED该机器的磁盘已经许诺给其他租户了。一台机器同时承载多位租户,磁盘是按剩余量而不是总量出售的——所以这个错误可能紧跟在一个通过了 DISK_TOO_LARGE 的 disk_gb 之后。响应中包含 available_disk_gb 和 requested_disk_gb按不超过 available_disk_gb 重试,或改选别的机器。available_disk_gb 可能为 0
422OFFER_NOT_VM_CAPABLE一个 vm 启动模式的模板被投放到了无法运行虚拟机的机器上把该模板部署到支持虚拟机的报价上,或改用其他启动模式的模板
404TEMPLATE_NOT_FOUND模板 id 不存在,或该模板已被删除使用模板库中的模板,或使用别人给你的 hash_id
404SSH_KEY_NOT_FOUND该 ssh_key_id 不属于你的密钥用 GET /v1/ssh-keys 列出并使用你自己账户下的 id。密钥属于用户,不属于组织
402PAYMENTS_FROZEN这个组织有一笔付款争议尚未结束。在它结束之前,部署和启动已停止的实例都会被暂停,其间已停止实例的 GPU 也会在机器支持的情况下被释放等争议结束。参见交易记录与花费和支付争议未结期间
409INSTANCE_LIMIT_REACHED这个组织已经有 25 个未销毁的实例。计入上限的不只是运行中的实例,已停止的和处于 error 的实例也算。响应中包含 limit销毁不再需要的实例——停止并不会腾出名额——然后再部署
422TEMPLATE_COMING_SOON这个模板的镜像还没有发布,因此无法启动换一个模板。控制台会把这类模板显示为暂不可用
422TEMPLATE_CUDA_TOO_NEW模板锁定了较旧的 CUDA 栈(即它的 cuda_max),而这台机器报告的 CUDA 版本更新。容器能起来,但其中的框架没有适用于这块 GPU 的内核选一台 CUDA 版本不高于模板上限的机器,或者选一个为较新 GPU 构建的模板
422TEMPLATE_ARCH_UNSUPPORTED模板声明的架构不是 x86_64。Superheat 的所有主机都是 x86_64使用 amd64 镜像
409OFFER_NOT_PINNABLE这份报价背后的机器没有在控制平面注册,部署无法固定到它上面。这类报价不会出现在市场里,所以这通常意味着你用的是一个过时的报价 id重新列出报价,另选一份
422TEMPLATE_REQUIRES_OWNER这个模板从私有镜像仓库拉取,只有拥有它的组织才能部署——它的仓库密码绝不会替别人使用复制这个模板,在副本上填入你自己的仓库凭据,然后部署副本

上表中的每个错误码都在保留任何东西之前返回,因此被拒绝时什么都不会创建,也不产生费用。

实例操作​

状态码代码成因处理方式
404INSTANCE_NOT_FOUND该实例 id 在本次请求所限定的组织中不存在检查 id,并确认你处在正确的组织中
409INVALID_STATE该操作在实例当前状态下不合法——例如停止一个正在停止的实例,或启动一个正在运行的实例。除 destroyed 外,任何状态下都允许销毁等实例进入 running 或 stopped 后再重试。实例的 allowed_actions 列出了此刻合法的操作。参见 实例状态
409HOST_UNREACHABLE你启动了一个已停止的实例,而它所在的机器此刻没有连接。实例仍是 stopped稍后再启动
409START_REFUSED主机拒绝恢复这个实例,或者已经不再持有它的工作负载——消息会说明是哪一种。实例仍是 stopped如果主机已经不再持有工作负载,就销毁实例并重新部署。否则稍后重试
409CAPACITY_UNAVAILABLE你启动的实例的 GPU 已被释放——余额到了零,或者一笔支付争议冻结了付款——而另一位租户现在正在使用其中一块。启动必须在同一台机器上取回同样的 GPU。实例仍是 stopped,磁盘还在稍后重试。如果等不及,就先把数据拷出来再销毁它。参见停止与销毁
503START_UNAVAILABLE恢复此刻无法完成。实例仍是 stopped;如果恢复其实已经生效,它会自行转到 running稍等片刻再试

实例为何失败​

这些不是对某个请求的拒绝,而是实例落入 error,或者一次停止或启动没有生效、实例回到 running 或 stopped 时所带的 error_code。实例页面会用你的控制台语言给出解释 —— 出错的实例显示在出了什么问题下,运行中或已停止的实例显示在上一个操作没有完成下 —— 代码本身写在下面,方便你把它报给支持人员。在其他状态下,页面会隐藏这两个字段,因为它们描述的是更早的状态。通过 API,它们就是实例上的 error_code 和 error_message。

平台自己设置的代码。控制台的解释会取代 API 返回的英文 error_message:

error_code控制台显示的内容
provision_failed调度器没有接受这次部署。未产生任何费用——请销毁后重试。
provision_lost部署从未到达调度器。未产生任何费用——请销毁后重试。
provision_timed_out工作负载始终没有被放置到机器上。请销毁后重试。
dispatch_job_missing调度器中已不存在此实例的工作负载。请销毁后重新部署。
stop_timed_out机器没有确认停止。实例仍在运行并计费,系统正在重试停止。
start_timed_out机器没有确认恢复。实例仍处于已停止状态——请再次尝试启动。
workload_completed工作负载已自行退出,其 GPU 已释放——请销毁此实例。
machine_unreachable启动时此实例所在的机器未连接。实例仍处于已停止状态——请稍后重试。
start_refused机器拒绝恢复此实例。实例仍处于已停止状态。
workload_gone机器上已不存在此实例的工作负载。请销毁后重新部署。
gpus_unavailable此实例在其机器上使用的 GPU 目前正被他人使用。实例仍处于已停止状态,磁盘完好——请稍后再启动,或将其销毁。
dispatch_unavailable无法连接调度器来恢复此实例。实例仍处于已停止状态——请稍后重试。
gateway_unavailable无法连接机器来恢复此实例。实例仍处于已停止状态——请稍后重试。

调度器针对机器上的工作负载记录的代码。控制台先显示解释,并在其下以详情显示主机自己的 error_message,它往往就是确切原因 —— 一个退出状态、一个缺失的镜像:

error_code控制台显示的内容
workload_failed容器在机器上运行失败。
workload_lost机器失去了对容器的追踪。
workload_exit_nonzero容器因错误退出。
workload_terminal工作负载在机器上已经结束。
start_timeout容器没有在规定时间内启动。很大的镜像下载时间可能超出允许范围。
deadline_exceeded工作负载达到了时间上限。
machine_lost机器已离线。
machine_gone机器已离开机群。
unknown_to_gateway机器上没有此工作负载的记录。
placement_error无法把工作负载放置到机器上。
drain机器因维护已停止服务。
manual_reschedule支持人员已把此工作负载迁移到另一台机器。
image_not_provisioning_capable此镜像无法以该模板的启动模式启动。
launch_mode_unsupported没有机器支持该模板的启动模式。
vm_not_supported这台机器无法运行虚拟机。

两张表里都没有的代码仍然会原样显示,并附上 API 发来的消息。接下来该怎么做,见故障排查。

浏览报价​

状态码代码成因处理方式
422INVALID_CURSORGET /v1/offers 的 cursor 不是 API 发出的,或者是为另一种 sort 发出的用同一个 sort 原样传回上一页的 next_cursor,或者省略它从头开始。参见报价

模板​

状态码代码成因处理方式
403TEMPLATE_IMMUTABLE你试图编辑或删除由 Superheat 精选维护的系统模板先复制一份,再编辑你的副本
409TEMPLATE_NAME_TAKEN你所在组织中已有同名模板(不区分大小写)换一个名称
404TEMPLATE_NOT_FOUND该 id 或 hash_id 无法解析到你可见的模板确认分享链接完整且是最新的——启动配置一变,hash_id 就会变
422INVALID_TAB模板列表接口的 tab 查询参数不属于模板库的任何一个标签页使用受支持的 tab 取值
422INVALID_CURSOR模板列表接口的 cursor 不是 API 发出的原样传回上一页的 next_cursor,或者省略它从头开始
409PUBLIC_TEMPLATE_LIMIT_REACHED你的组织已经有 50 个公开模板。响应里带有 limit先把其中一个改为私有或删掉,再发布新的

SSH 密钥​

状态码代码成因处理方式
422INVALID_SSH_KEY该值不是一行 OpenSSH 公钥、密钥内容不是有效的 base64,或者密钥类型不受支持把 .pub 文件的全部内容粘贴成一行,以密钥类型开头。参见 受支持的密钥类型
409DUPLICATE_SSH_KEY你已经添加过指纹相同的密钥直接用已有的那把密钥,或先删除旧条目
404SSH_KEY_NOT_FOUND该密钥 id 不是你的密钥按用户隔离。别的成员的密钥你永远看不到

团队与邀请​

状态码代码成因处理方式
400PERSONAL_ORG你试图把别人邀请进个人组织先创建一个真正的组织,再从那里发邀请
404INVITE_NOT_FOUND邀请令牌不正确、该邀请已被撤回,或者它发送到的邮箱和你当前登录的邮箱不同用受邀的邮箱登录,或者请管理员重新发一个链接
410INVITE_REVOKED发出邀请的人已经不再是这个组织的管理员,所以邀请已失效向现任管理员索取新的邀请
410INVITE_USED该邀请已被接受请对方重新发一个邀请链接
410INVITE_EXPIRED该邀请已过期请对方重新发一个邀请链接
404MEMBER_NOT_FOUND该用户不是本组织的成员刷新团队页面——对方可能已被移除
400LAST_ADMIN移除或降级该成员会让组织没有任何管理员先把另一名成员提升为管理员

余额​

状态码代码成因处理方式
422INVALID_AMOUNT自定义充值金额缺失或超出可接受范围选择 $10、$25 或 $100 的充值包,或填写 $5 到 $1,000 之间的自定义金额
403ADMIN_REQUIRED由成员或使用 API 密钥发起了付款请组织管理员来充值
422INVALID_TIME_ZONE传给 GET /v1/billing/spend-daily 的 tz 不是 API 认识的 IANA 时区名传入 Europe/Berlin 这样的名称,或者省略 tz 使用 UTC

API 密钥​

状态码代码成因处理方式
404API_KEY_NOT_FOUND该密钥 id 在本组织中不存在重新列出你的密钥并使用当前有效的 id
403ADMIN_REQUIREDAPI 密钥试图创建或吊销另一个 API 密钥,或成员试图管理团队级密钥在已登录的会话中创建和吊销密钥

校验失败的请求​

如果请求的正文或查询字符串不符合 schema,它会在到达上述任何检查之前就被拒绝。这类请求返回 422,detail 下是一组字段错误,而不是一个 code:

{
"detail": [
{
"type": "less_than_equal",
"loc": ["body", "disk_gb"],
"msg": "Input should be less than or equal to 20000"
}
]
}

loc 条目指出了出问题的字段。值得记住的边界是:disk_gb 介于 10 和 20,000 之间,label 最长 64 个字符,日志接口上的 tail 介于 1 和 1,000 之间。模板和部署方面:环境变量条目最多 100 个(模板上和 env_overrides 里都是),每个值最长 4,096 个字符;端口最多 32 个;约束选择器最多 32 个;cuda_min、cuda_max 和 arch 最长 32 个字符;模板和报价列表接口的 limit 介于 1 和 200 之间;报价列表接口的 q 最长 100 个字符。

相关内容​