Before sharing our container recipe for SaladCloud, we deployed it through the SaladCloud public API exactly as a new user would. It did not work the first time. These are the seven things we learned, each one confirmed by a real deployment.

1. GPU classes are IDs, not names

Our first recipe listed GPUs as rtx-3090, rtx-4090 and so on. The API rejected it with HTTP 400 and "The input was not valid" for every entry. The gpu_classes field expects the GPU class IDs, which you can list with GET /organizations/<org>/gpu-classes. Each class also comes with its current price per priority level, which is useful when you choose them.

2. The display name has a strict character set

A display name with parentheses was rejected. The API requires it to match ^[ ,-.0-9A-Za-z]+$, so letters, digits, spaces, commas, periods and hyphens only.

3. HTTP readiness probes need a headers field

An HTTP readiness probe without headers was rejected. An empty list, "headers": [], is enough.

4. A 503 from the Container Gateway can mean IPv6

This one cost us the most time. Our container started, Jupyter was running, and from inside the container /api answered 200. Yet the instance never became ready, and the gateway URL answered 503. Switching the readiness probe from HTTP to TCP changed nothing.

The cause is in SaladCloud's troubleshooting guide: the Container Gateway reaches your container over IPv6, so a server bound only to 0.0.0.0 gets 503 errors. Jupyter had been started with --ip=0.0.0.0. After starting it with --ip=::, which accepts both IPv4 and IPv6, the instance became ready about 35 seconds after it started running, with both a TCP probe and an HTTP probe on /api, and the gateway answered normally. In our tests, the readiness probe itself also only passed once the server listened on ::.

If your web server, notebook or API sits behind the Container Gateway, check the address it binds to first.

5. You can validate a recipe without paying for a GPU

Create the container group with "autostart_policy": false. The API still validates the whole configuration and returns 201 if it is accepted, but nothing is allocated. Delete the group right after. We used this to fix the first three problems in minutes instead of waiting for a node each time.

6. Deleted group names can stay taken for a while

Re-creating a container group under a name we had just deleted returned a name_conflict error, even after the delete had gone through. Using a fresh name for each test run avoided it.

7. SSH uses the keys registered on your account

SSH into a running instance worked with the key registered on our SaladCloud account and was refused with a newly generated key that was never registered. If SSH says Permission denied (publickey), check the keys on your account rather than inside the container. We also found that commands sent over that SSH connection ran correctly only when wrapped in bash -c '...'; without it, a line like echo A; whoami was printed back instead of being run.

Why we are writing this

We build SpotWarp, a small client that backs up a SaladCloud container's /workspace to your own machine and restores it onto a replacement node. We would rather publish what went wrong in our own testing than claim everything worked first time. Our recipe is in the GitHub repository.

Sources: SaladCloud troubleshooting guide and our own deployments through the SaladCloud public API on October 21, 2026.