Hetzner API errors and what Hetscale does
Last updated
Hetscale sorts every error answer from the Hetzner Cloud API into a fixed class, and each class has
one response: try again, try the next location or type, treat it as done, wait, or stop and tell
you. A 429 is never read as a server gone. A delete that Hetzner’s delete protection refused is
not retried on its own. No error makes Hetscale shut down or delete a server it did not create. The
answers below use the codes of Hetzner’s API reference, as read on 18 October 2026.
What does Hetscale do with each Hetzner answer?
| Hetzner’s answer | What it means | What Hetscale does |
|---|---|---|
5xx, timeouts, 409 conflict |
Hetzner’s API could not answer, did not answer in time, or the resource changed during the request | Tries again, and the node group does not pause. A create is sent again under the same request and name, so it never makes a second server. After repeated errors in a row for one location and type, the next step of the fallback chain is tried. A failed read decides nothing: no server is read as gone, and no server is removed while metrics are missing. |
412 resource_unavailable |
Hetzner cannot supply that server type in that location right now | Records “Out of stock (412)”. Then tries the next location of the load balancer’s network zone and, in a fallback mode you chose, your other types. When the whole chain is out, the node group is short of capacity: Needs you lists it as “Short of capacity”, and it waits for stock. Running servers are not touched (When your Hetzner server type is sold out). Hetscale reads the error code in the answer’s body, not the status alone, because several Hetzner errors answer 412, as Hetzner advises. A restricted account gets the same answer: Hetscale then reads your project’s own server type list once, and if it shows the location unavailable to your account, your groups skip that location and other customers’ groups do not (Hetzner support, October 2026). Hetzner’s other 412 answers fall under the last row. |
403 resource_limit_exceeded |
A limit of your Hetzner account is reached, such as its servers, vCPUs or Primary IPs | Stops: the new server is not created, the node group pauses with “Hetzner account limit reached”, naming the limit when Hetzner’s answer does, and you get a mail. Running servers keep running. Raise the limit in the Hetzner Console, or free what it counts, then Resume (Hetzner limits that shape a node group). |
409 uniqueness_error, 422 target_already_defined |
The name is already taken; the server is already a target of the load balancer | Treated as done, after a check. On a create, Hetscale reads the server that holds the name. It takes that server as the new one only when its labels name that node and its create request, which is what a retry after a lost answer finds (“Already created”). Any other server of that name is neither taken nor touched: the new node fails, and you get a security alert. A placement group whose name is taken is taken over only when its labels name it; otherwise the server is created without spread. A server already among the load balancer’s targets counts as added. |
423 locked, 423 protected |
locked: another action is running on that resource. protected: its delete protection is on |
locked: waits and tries again (“Locked”). protected when Hetscale removes a server: the removal stops, the server is not deleted, the timeline records “Stopped by delete protection”, and you get a mail. The node group is not paused. Hetscale does not retry the removal on its own and never turns protection off. Once you turn protection off in the Hetzner Console, Try the delete again on the Servers page sends it again (Security). |
429 rate_limit_exceeded |
The project’s API budget is spent; Hetzner counts it per project, for every token of the project | Backs off. Until Hetzner’s rate-limit headers show a request is available again, Hetscale decides nothing for the project’s node groups and requests no new server. A step already under way that meets a 429 waits. A 429 is never read as a missing server. Polling keeps a reserve so that creating, draining and deleting servers find budget. |
422 placement_error |
Hetzner could not place the server apart from the other servers of its placement group | Creates the server again at once, without the placement group, under the same request. It serves like any other server. The Servers page marks it “Not spread”, and the timeline records “Created without spread”. When you run Replace older servers on the Servers page, it is moved into a placement group (Placement groups). |
Anything else, such as 401, 403 maintenance, another 403 or another 422 |
An answer Hetscale does not try again. 403 maintenance is one: Hetzner gives it while it maintains its API |
Stops instead of guessing. A node group that creates and removes servers (in Rehearsal or Live) pauses with “Hetzner answered with an error”, its timeline names the error, and you get a mail. A node group that only observes is not paused; the mail says Hetscale could not read the project. When Hetzner no longer accepts the project’s token, or the token can only read, the mail says that (A node group is paused, Replace a project’s token). |
What does Hetscale never do on a Hetzner error?
- Read a
429, a timeout or a server error as a server gone. - Create a second server for one request. A retry carries the same name, and a server that already holds the name is checked before it is taken.
- Take over, shut down or delete a server whose labels and name do not match the node Hetscale expects. The ownership guard checks every shutdown and delete (Security).
- Retry on its own a delete that delete protection refused, or turn protection off.
- Remove a server because metrics are missing.
Where do I see what Hetzner answered?
The node group’s Capacity & cost page lists each create step over the history your plan keeps, with its outcome: “Created”, “Already created”, “Out of stock (412)”, “Account limit reached (403)”, “Rate limited”, “Hetzner error”, “Locked” or “Refused”. With Hide skipped steps switched off, it also lists the steps skipped without a call: “Skipped: out of stock”, “Skipped: a recent 412” and “Skipped: waiting to retry”. The node group’s Timeline records every pause, every failed server and every server created without spread, each with its reason, and every alert mail links to it.
What does this page not cover?
The messages the panel shows when it checks a token before storing it are on A token is refused. Why a node group paused, and how to resume it, is on A node group is paused. Hetzner’s own list of error codes is in its API reference. The limits behind the account-limit and rate-limit answers are on Hetzner limits that shape a node group.