Skip to main content

Error codes

When something is refused, the reason arrives as a short machine-readable code. The console turns most of them into a toast in your console language; a code it does not know yet shows the API's own message, which is in English. The API returns them as JSON.

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

A few codes carry extra fields alongside code and message — DISK_TOO_LARGE returns max_disk_gb and MACHINE_DISK_EXHAUSTED returns available_disk_gb, so a client can clamp the slider and retry without a second round trip.

Those two are not interchangeable, and clamping to the wrong one loops forever. max_disk_gb is the machine's total disk; available_disk_gb is what is left after the other renters on it and a 50 GB host reserve. A machine can therefore pass DISK_TOO_LARGE and still answer MACHINE_DISK_EXHAUSTED — even an empty one, because the reserve is never sellable. Clamp to available_disk_gb when you get it.

Authentication and organization scope​

StatusCodeCauseWhat to do
401TOKEN_INVALIDNo Authorization header, a malformed token, an unknown or revoked API key (removing a member revokes the personal keys they created), or an API key sent to an account endpointSend a valid bearer token. Account endpoints such as /v1/me and /v1/ssh-keys need a signed-in session, not an shk_ key
401TOKEN_EXPIREDThe session token is past its expirySign in again. For unattended scripts, use an API key instead
403NOT_A_MEMBERX-Org-Id names an organization you do not belong toDrop the header to use your personal organization, or ask an admin for an invite
403ORG_MISMATCHX-Org-Id does not match the organization the API key was created inRemove the header, or use a key belonging to that organization
403ADMIN_REQUIREDAn admin-only action — top-up orders, 发票 details, invites, member management, team API keys — attempted as a member or with an API keyAsk an admin, or repeat the action from a signed-in admin session
400INVALID_ORG_IDX-Org-Id is not a valid idCopy the id from GET /v1/orgs
403MFA_REQUIREDYour account has two-factor authentication enrolled, and the session token has not completed the second stepSign in again and enter the code from your authenticator app. The console sends you to that step itself. API keys are not affected
503AUTH_UNAVAILABLEThe API cannot check your sign-in right now — the signing keys or the two-factor state could not be readRetry shortly. Your session is still valid

Limits on every request​

StatusCodeCauseWhat to do
429RATE_LIMITEDToo many requests from one caller — a signed-in user, an API key, or for anonymous requests an IP address. Every /v1 request counts toward 600 a minute; POST, PUT, PATCH and DELETE also count toward 60 a minute. An IP address whose requests are refused as unauthenticated more than 60 times a minute gets this too, for every credential from it that has not already workedWait the seconds in the Retry-After header (also retry_after_s in the body), then retry. /v1/health and payment notifications are never limited
413PAYLOAD_TOO_LARGEThe request body is larger than the endpoint accepts: 1 MiB for most endpoints, 4 MiB under /v1/templates. The response includes limit_bytesSend a smaller body. A template's readme and on-start script have their own caps, well inside that

Deploying​

StatusCodeCauseWhat to do
402INSUFFICIENT_BALANCEYour balance does not cover one hour of the organization's burn with this instance running — its GPU and disk, plus the GPU and disk of instances running, starting or being created and the disk of stopped ones — when you deploy or start it. Being above zero is not enough. The response includes balance_micro and required_microAdd credits. Only an admin can top up
409OFFER_UNAVAILABLEThe last free unit of that shape was taken between the moment you opened it and the moment you deployed — or by another deploy while yours was being reservedGo back to the marketplace and pick another offer. The count on a card is a snapshot; the deploy is what decides
404OFFER_NOT_FOUNDGET /v1/offers/{id} was given an id that does not exist or has been withdrawn from the catalog. A deploy against an unknown offer returns OFFER_UNAVAILABLE insteadRe-list offers and use a current id
422DISK_TOO_LARGEThe requested disk_gb is more than the machine has in total. The response includes max_disk_gbRequest no more than max_disk_gb, or choose a machine with a larger disk
409MACHINE_IN_MAINTENANCEThe machine is booked to go offline too soon to start an instance on it. The response includes next_maintenancePick another machine, or come back after the window. A window further out does not block a deploy — it is shown on the offer instead
409MACHINE_DISK_EXHAUSTEDThe machine's disk is already committed to other renters. It carries several at once, and disk is sold against what is left, not against the total — so this can follow a disk_gb that cleared DISK_TOO_LARGE. The response includes available_disk_gb and requested_disk_gbRetry at or below available_disk_gb, or pick another machine. available_disk_gb can be 0
422OFFER_NOT_VM_CAPABLEA vm launch-mode template was aimed at a machine that cannot run virtual machinesDeploy the template onto a VM-capable offer, or pick a template in another launch mode
404TEMPLATE_NOT_FOUNDThe template id does not exist, or the template has been deletedUse a template from the gallery, or a hash_id you were given
404SSH_KEY_NOT_FOUNDThe ssh_key_id is not a key this credential may attach: not one of your own, or — with a team API key — not a current member'sList GET /v1/ssh-keys with a session token and use an id from your own account. Keys belong to a user, not to an organization
409INSTANCE_LIMIT_REACHEDThe organization already has 25 instances that are not destroyed — stopped, error and still-destroying ones count. The response includes limitDestroy instances you no longer need, including any in error. The console says "You’ve reached the instance limit for this organization. Destroy one first."
422TEMPLATE_COMING_SOONThe template is marked coming soon: its image is not published yet — on Superheat CN, for example, the NVIDIA NGC (nvcr.io) templatesPick another template. The console will not let you select one, so this usually reaches API callers only
422TEMPLATE_CUDA_TOO_NEWThe template pins an older CUDA stack (cuda_max) and the machine reports a newer CUDAPick a machine whose CUDA is within the template's ceiling, or another template
422TEMPLATE_ARCH_UNSUPPORTEDThe template declares an architecture other than amd64/x86_64; Superheat hosts are x86_64Use a template with an x86_64 image
422TEMPLATE_REQUIRES_OWNERThe template belongs to another organization and pulls from a private registry with credentials, so only the owning organization can deploy it. The console says "This template pulls from a private registry and can only be deployed by the organization that owns it."Duplicate it into your organization and enter your own registry credentials (if you can pull that image), or ask the owner to deploy
409OFFER_NOT_PINNABLEThe offer's machine is not registered with the fleet's control plane, so a deploy cannot be pinned to it. Listings never show such an offer; you meet this only with a stale offer_id. The console says "This machine can’t take deployments right now. Pick another one."Re-list offers and pick another

Every code in this section comes back before anything is kept, so a refused deploy creates nothing and costs nothing.

Instance actions​

StatusCodeCauseWhat to do
404INSTANCE_NOT_FOUNDThe instance id does not exist in the organization the request is scoped toCheck the id, and check you are in the right organization
409INVALID_STATEThe action is not legal from the instance's current state — stopping something already stopping, starting something that is running. Destroy is allowed from every state except destroyedWait for the instance to reach running or stopped, then retry. The instance's allowed_actions lists what is legal now. See Instance states
409HOST_UNREACHABLEYou started a stopped instance, and the machine it lives on is not connected right now. The instance is still stoppedStart it again later
409START_REFUSEDThe host refused to resume the instance, or no longer holds its workload — the message says which. The instance is still stoppedIf the host no longer holds the workload, destroy the instance and deploy again. Otherwise retry later
503START_UNAVAILABLEThe resume could not be completed right now. The instance is still stopped; if the resume lands after all, it moves to running on its ownRetry shortly
409CAPACITY_UNAVAILABLEYou started an instance whose GPUs were released when the balance ran out (an auto-stopped instance, or one you had stopped yourself), and the GPUs it used on that machine are now in use by someone else or out of service. The instance is still stopped, with its disk intact. The console says "The GPUs this instance used are in use by someone else right now, so it can’t start. It’s still stopped with its disk — try again later."Start it again later: nothing can reach the disk until a start succeeds. If it keeps failing, the only way forward is to destroy the instance, which deletes the disk, and deploy again. See After the GPUs are released

Why an instance failed​

These are not refusals of a request: they are the error_code an instance carries when it lands in error, or when a stop or a start did not land and the instance went back to running or stopped. The instance page shows the explanation in your console language — under What went wrong on an errored instance, and under The last action did not complete on a running or stopped one — with the code itself underneath, so you can quote it to support. In any other state the page hides the fields, because they describe an earlier state. Over the API they are error_code and error_message on the instance.

Codes the platform sets itself. The explanation replaces the API's English error_message:

error_codeWhat the console says
provision_failedThe scheduler did not accept this deploy. Nothing was billed — destroy it and try again.
provision_lostThe deploy never reached the scheduler. Nothing was billed — destroy it and try again.
provision_timed_outThe workload was never placed on its machine. Destroy it and try again.
dispatch_job_missingThe scheduler no longer has this instance’s workload. Destroy it and deploy again.
stop_timed_outThe machine did not confirm the stop. The instance is still running and billing; the stop is being retried.
start_timed_outThe machine did not confirm the resume. It’s still stopped — try starting it again.
workload_completedThe workload exited on its own. Its GPU has been released — destroy the instance.
machine_unreachableThe machine this instance lives on wasn’t connected when it was started. It’s still stopped — try again later.
start_refusedThe machine refused to resume this instance. It’s still stopped.
workload_goneThe machine no longer holds this instance’s workload. Destroy it and deploy again.
dispatch_unavailableThe scheduler couldn’t be reached to resume this instance. It’s still stopped — try again shortly.
gateway_unavailableThe machine couldn’t be reached to resume this instance. It’s still stopped — try again shortly.
gpus_unavailableThe GPUs this instance used on its machine are in use by someone else right now. It’s still stopped with its disk — try starting it later, or destroy it.

workload_gone has two sources: the machine no longer held the workload when a start reached it, or the instance's container disappeared from the machine while the instance was stopped. In the second case the instance moves to error, stops billing, and can only be destroyed.

Codes the scheduler records about the workload on its machine. The console shows the explanation and, under it as Details, the host's own error_message, which is often the exact reason — an exit status, a missing image:

error_codeWhat the console says
workload_failedThe container failed on its machine.
workload_lostThe machine lost track of the container.
workload_exit_nonzeroThe container exited with an error.
workload_terminalThe workload had already finished on its machine.
start_timeoutThe container did not start in time. A very large image can take longer than allowed to download.
deadline_exceededThe workload reached its time limit.
machine_lostThe machine went offline.
machine_goneThe machine left the fleet.
unknown_to_gatewayThe machine has no record of this workload.
placement_errorThe workload could not be placed on a machine.
drainThe machine was taken out of service for maintenance.
manual_rescheduleSupport moved this workload to another machine.
image_not_provisioning_capableThis image can’t be started with this template’s launch mode.
launch_mode_unsupportedNo machine supports this template’s launch mode.
vm_not_supportedThis machine can’t run virtual machines.

A code missing from both tables still shows, verbatim, with the message the API sent. What to do next is in Troubleshooting.

Browsing offers​

StatusCodeCauseWhat to do
422INVALID_CURSORThe cursor on GET /v1/offers is not one the API issued, or was issued for a different sortPass back the next_cursor of the previous page unchanged with the same sort, or omit it to start over. See Offers

Templates​

StatusCodeCauseWhat to do
403TEMPLATE_IMMUTABLEYou tried to edit or delete a system template curated by SuperheatDuplicate it first, then edit your copy
409TEMPLATE_NAME_TAKENYour organization already has a template with that name, ignoring caseChoose a different name
404TEMPLATE_NOT_FOUNDThe id or hash_id does not resolve to a template you can seeConfirm the share link is complete and current — a hash_id changes when the launch recipe changes
422INVALID_TABThe tab query parameter on the template listing is not one of the gallery tabsUse a supported tab value
422INVALID_CURSORThe cursor on the template listing is not one the API issuedPass back the next_cursor of the previous page unchanged, or omit it to start over
409PUBLIC_TEMPLATE_LIMIT_REACHEDYour organization already has 50 public templates. The response includes limitMake one of them private, or delete one, before publishing another

SSH keys​

StatusCodeCauseWhat to do
422INVALID_SSH_KEYThe value is not an OpenSSH public key line, the key material is not valid base64, or the type is not supportedPaste the whole contents of the .pub file, one line, starting with the key type. See Supported key types
409DUPLICATE_SSH_KEYYou already added a key with the same fingerprintUse the key you already have, or delete the old entry first
404SSH_KEY_NOT_FOUNDThe key id is not yoursKeys are per user. Another member's key is never visible to you

Team and invites​

StatusCodeCauseWhat to do
400PERSONAL_ORGYou tried to invite someone into a personal organizationCreate a real organization first, then invite from there
404INVITE_NOT_FOUNDThe invite token is wrong, the invite was withdrawn, or it was sent to a different email address than the one you are signed in withSign in with the invited address, or ask an admin for a fresh link
410INVITE_REVOKEDWhoever sent the invite is no longer an admin of the organization, so it is no longer validAsk a current admin for a new invite
410INVITE_USEDThe invite has already been acceptedAsk for a new invite link
410INVITE_EXPIREDThe invite is past its expiryAsk for a new invite link
404MEMBER_NOT_FOUNDThe user is not a member of this organizationRefresh the team page — they may have been removed already
400LAST_ADMINRemoving that member, or demoting them, would leave the organization with no adminPromote another member to admin first

Credits​

StatusCodeCauseWhat to do
422INVALID_AMOUNTamount_minor is neither a pack amount nor between ¥20 and ¥10,000. The response includes min_minor and max_minor in 分 (by default 2000 and 1000000)Pick a ¥50, ¥100 or ¥500 pack, or an amount from min_minor to max_minor
422PROVIDER_NOT_ENABLEDThe payment method you asked for is not open on this site: any order before top-ups open, or wechat before the domain moves to HTTPSPick one from providers in GET /v1/billing/config. While that list is empty you cannot top up online
503PROVIDER_NOT_CONFIGUREDThe payment method is enabled but its credentials on the server are incompleteA server configuration problem, not a fault in your request. Retry later, and write to finance@superheat.cloud if it persists
429TOO_MANY_OPEN_ORDERSYou already hold five unpaid, unexpired codesPay one of them, or let them expire (15 minutes). Asking again for the same method and amount in the same organization (not for an invoice order) returns the code you have, as long as it has more than two minutes left. The limit of five counts your codes across all organizations
422INVOICE_PROFILE_REQUIREDAn order was placed with want_invoice: true but the organization has no saved 发票 detailsSave them first with PUT /v1/billing/invoice-profile, or switch on Request an invoice (fapiao) (开具发票) in the console and fill in the form
404ORDER_NOT_FOUNDThe order id does not exist in the organization the request is scoped toCheck the id, and check you are in the organization that placed the order
403ADMIN_REQUIREDA member or an API key tried to create a top-up order or to read or write the 发票 detailsAsk an organization admin to add credits. See Adding credits
422INVALID_TIME_ZONEGET /v1/billing/spend-daily was given a tz that is not an IANA time zone name the API knowsSend a name such as Asia/Shanghai, or omit tz for UTC

API keys​

StatusCodeCauseWhat to do
404API_KEY_NOT_FOUNDThe key id does not exist in this organizationRe-list your keys and use a current id
403ADMIN_REQUIREDAn API key tried to create or revoke another API key, or a member tried to manage a team-level keyCreate and revoke keys from a signed-in session

Requests that fail validation​

A request whose body or query string does not match the schema is rejected before it reaches any of the checks above. It returns 422 with a list of field errors under detail instead of a code:

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

The loc entry names the offending field. The bounds worth remembering are disk_gb between 10 and 20,000, a label of at most 64 characters, and tail on the logs endpoint between 1 and 1,000. On templates and deploys: at most 100 environment entries on the template and, counted separately, 100 in env_overrides, each value up to 4,096 characters; at most 32 ports; at most 32 constraint selectors; cuda_min, cuda_max and arch up to 32 characters; limit on the template and offer listings between 1 and 200; q on the offer listing up to 100 characters.