DEV Community

Gonzalo Gjuka
Gonzalo Gjuka

Posted on Originally published at controlcloud.dev on

OCI "Out of host capacity" on A1.Flex: a retry loop with the CLI, and the two checks to do first

Oracle's Always Free tier gives every tenancy 1,500 OCPU-hours and 9,000 GB-hours a month of VM.Standard.A1.Flex, which is a 2 OCPU / 12 GB Arm VM running all month. It also gives, in many regions, the same answer every time you press Create:

Out of host capacity.
Enter fullscreen mode Exit fullscreen mode

Three days of that in sa-saopaulo-1 produced the loop below. It is nothing clever; the value is in what to check before running it, because two of the reasons people wait for weeks are not capacity at all.

Check 1: quota is not capacity

The error says the host pool has no room for your shape. It does not say anything about your tenancy's limit, and the limit is the thing that can block you forever while you blame the pool. Read it:

T=<tenancy OCID>
AD=$(oci iam availability-domain list --compartment-id "$T" --query 'data[0].name' --raw-output)
oci limits resource-availability get --compartment-id "$T" \
  --service-name compute --limit-name standard-a1-core-count \
  --availability-domain "$AD" --query 'data.{available:available,used:used}'
Enter fullscreen mode Exit fullscreen mode

If available is 0, no amount of retrying will help: you are at the A1 core limit (2 OCPU for an Always Free tenancy) and something, perhaps a half-created instance from an earlier attempt, is holding it. If available is 2, the loop makes sense.

Check 2: home region, not any region

Always Free compute only counts in the tenancy's home region, and the home region is fixed when the account is created. Oracle's own page says it plainly: "You must create the Always Free compute instances in your home region." So a report that "Mumbai has capacity" helps you only if Mumbai is your home region. On Pay As You Go the Always Free allowance still applies in the home region, and an A1 in any other region is a paid instance at list price, which for some people is the right answer.

In regions with more than one availability domain, A1 can be created in any AD; data[0].name above picks the first one. Rotate the AD per attempt if your region has three.

The loop

The console's retry only lives while the tab is open. This runs on any machine with a working ~/.oci/config and stops at the first success. A failed launch call takes about 100 seconds to come back, so with a two-minute sleep it is roughly ten attempts an hour, which is well under the API rate limit; on a 429 it backs off five minutes.

#!/usr/bin/env bash
# needs a working ~/.oci/config; fill T (tenancy or compartment OCID), SUBNET, IMAGE, PUBKEY
set -u
T=${T:?} SUBNET=${SUBNET:?} IMAGE=${IMAGE:?} PUBKEY=${PUBKEY:-~/.ssh/id_ed25519.pub}
NAME=${NAME:-a1} SLEEP=${SLEEP:-120}
AD=$(oci iam availability-domain list --compartment-id "$T" --query 'data[0].name' --raw-output)

try() {
  local ocpus="$1" mem="$2" out
  out=$(oci compute instance launch \
    --compartment-id "$T" --availability-domain "$AD" \
    --display-name "$NAME" --shape VM.Standard.A1.Flex \
    --shape-config "{\"ocpus\":$ocpus,\"memoryInGBs\":$mem}" \
    --image-id "$IMAGE" --subnet-id "$SUBNET" --assign-public-ip true \
    --ssh-authorized-keys-file "$PUBKEY" \
    --query 'data.{id:id,st:"lifecycle-state"}' 2>&1)
  if grep -q '"id": "ocid1.instance' <<<"$out"; then
    echo "$(date -u +%FT%TZ) OK ${ocpus}/${mem}: $out"
    grep -o 'ocid1\.instance[^"]*' <<<"$out" > ~/a1-retry.ok
    return 0
  fi
  echo "$(date -u +%FT%TZ) no ${ocpus}/${mem}: $(grep -o '"message": "[^"]*"' <<<"$out" | head -1)"
  grep -qi 'TooManyRequests\|429' <<<"$out" && sleep 300
  return 1
}

n=0
while :; do
  n=$((n+1)); echo "--- round $n"
  try 2 12 && break
  try 1 6 && break
  sleep "$SLEEP"
done
echo "instance: $(cat ~/a1-retry.ok)"
oci compute instance list-vnics --instance-id "$(cat ~/a1-retry.ok)" \
  --query 'data[0]."public-ip"' --raw-output
Enter fullscreen mode Exit fullscreen mode

Start it with nohup ./a1-retry.sh > a1-retry.log 2>&1 & and forget it. It tries the full 2/12 first and then 1/6; A1 resizes in place later, so taking the smaller one when it appears costs nothing. The image OCID is per region (oci compute image list --compartment-id "$T" --operating-system "Canonical Ubuntu" --shape VM.Standard.A1.Flex lists the Arm ones).

What the thread taught me

I posted the loop on r/oraclecloud and the replies were more useful than the script. One person waited six months in Ashburn retrying every 30 seconds from the console, which is the single-AD, single-shape version of this problem and the reason to rotate ADs. Two people got A1 in Mumbai within hours, one of them on Pay As You Go, which is consistent with Oracle's note that upgrading "gives you access to more types of Compute resources". And nobody, including me, has a timestamp for when São Paulo frees up, which is why the loop logs every attempt: if it ever lands, the log says at what hour, and that is the only data anyone has.

Once it exists

Keep the instance busy. Oracle reclaims idle Always Free instances after seven days under 20 % CPU, network and memory at the 95th percentile. And an instance you fought three days for deserves to be on the list of what you run: I build Control Cloud, which reads the tenancy through the API with a read-only credential and shows the A1 next to everything else, including the boot volume it leaves behind if you ever terminate it without ticking "permanently delete". Free plan: 1 operator, 1 provider.

Top comments (0)