Documentation

esc
    API reference · Using the API / Errors

    Errors

    Every error is a problem document with a stable code. Branch on the code, show the detail, and retry only what is worth retrying.

    The shape of an error

    Every error is application/problem+json (RFC 9457):

    JSON
    {
      "type": "https://api.pantechdynamics.com/problems/insufficient-credit",
      "title": "Insufficient credit",
      "status": 402,
      "code": "INSUFFICIENT_CREDIT",
      "detail": "This instance needs NGN 15,040.00 of credit upfront and NGN 2,000.00 is available. Top up your credit or add a card, then try again.",
      "request_id": "req_6Yq8mB2x0dKpL4vS"
    }
    • code is the stable, machine-readable reason. Branch on it. It never changes within v1.
    • detail explains this occurrence for a person. Show it, log it, but do not parse it, because its wording can change.
    • request_id identifies the request. Quote it to support.

    request_id is also in every response's X-Request-Id header, errors or not, so log it with each call you make.

    A validation error lists every bad field in errors, so you can fix them all at once:

    JSON
    {
      "status": 422,
      "code": "VALIDATION_FAILED",
      "title": "Validation failed",
      "detail": "plan_slug: must identify an active plan.",
      "request_id": "req_6Yq8mB2x0dKpL4vS",
      "errors": [
        { "field": "plan_slug", "code": "PLAN_NOT_FOUND", "message": "must identify an active plan" }
      ]
    }

    Its detail names each bad field and what it must be (field: message, separated by ;), so it is useful on its own. Show each entry of errors beside its field, and branch on its code.

    By status

    StatusMeansRetry?
    400The request could not be readNo, fix it
    401No valid API keyNo, fix the key
    402Not enough credit to payAfter topping up
    403The key may not do thisNo
    404Nothing with that id in your organizationNo
    409Not possible in the resource's current stateSometimes; see the code
    413Body over 64 KiBNo
    422A field is invalid; see errorsNo, fix it
    429Rate limitedYes, after Retry-After
    500, 503Our side failedYes, with backoff and the same Idempotency-Key

    Request and authentication codes

    codeStatusWhat to do
    INVALID_REQUEST_BODY400Send valid JSON
    IDEMPOTENCY_KEY_REQUIRED400Add an Idempotency-Key header
    INVALID_IDEMPOTENCY_KEY400Keep the key to 255 characters
    INVALID_FILTER400Use a listed filter value
    INVALID_CURSOR400Start the list again without a cursor
    INVALID_PAGE400Send a limit from 1 to 100, or leave it out for 50
    INVALID_CALLER_ADDRESS400Retry from a normal internet connection
    UNAUTHENTICATED401Send a valid, unexpired key, and check the URL starts with /public/v1
    INSUFFICIENT_SCOPE403Use a key with write scope
    FORBIDDEN403The key's creator lacks the role for this
    RESOURCE_NOT_FOUND404Check the id and the organization
    NOT_FOUND404The feature is not offered yet
    ROUTE_NOT_FOUND404Check the method and path
    REQUEST_TOO_LARGE413Send a smaller body
    VALIDATION_FAILED422Fix each field in errors
    RATE_LIMITED429Wait Retry-After seconds
    INTERNAL500Retry with backoff; quote request_id if it persists

    Account and billing codes

    codeStatusWhat to do
    INSUFFICIENT_CREDIT402Top up credit or add a card in the console
    ACCOUNT_NOT_ACTIVE409Finish activating billing in the console
    ACCOUNT_SUSPENDED409Pay the overdue invoice; nothing new can be created until then
    PROVIDER_ACCOUNT_NOT_READY409Your account is still being set up; retry in a minute
    STATIC_NAT_LIMIT_EXCEEDED403Your organization has as many one-VM public IPs as it may. Release one, or contact support for a higher limit
    PUBLIC_IP_LIMIT_EXCEEDED403Your organization has as many public IPs, of any purpose, as it may (20 by default). Release one, or contact support for a higher limit
    CREDIT_PURCHASE_UNAVAILABLE409Finish billing setup in the console
    EMAIL_VERIFICATION_REQUIRED409The key's creator must verify their email first
    AMOUNT_OUT_OF_RANGE422Buy an amount within the per-purchase limits
    BILLING_UNAVAILABLE503Retry in a few seconds

    Resource state codes

    These mean the request was fine but the resource cannot do it now.

    codeStatusWhat to do
    INVALID_RESOURCE_STATE409Wait for the resource to settle, then retry
    CONCURRENT_UPDATE409Retry the same request with the same key
    IDEMPOTENCY_CONFLICT409Use a new Idempotency-Key for a different request
    INSTANCE_NAME_TAKEN409Choose another name
    INSTANCE_MUST_BE_STOPPED409Stop the instance first
    INSTANCE_HAS_PUBLIC_IP409A public IP still points at it. Detach the address to keep it, or release it, first
    INSTANCE_HAS_PORT_FORWARDS409Delete its port forwards first
    INSTANCE_ALREADY_HAS_PUBLIC_IP409It has a static NAT address already; detach or release that one first
    CONSOLE_INSTANCE_NOT_RUNNING409Start the instance first
    SSH_ACCESS_INSTANCE_NOT_RUNNING409Start the instance first
    SSH_ACCESS_SECURITY_GROUP_SHARED409Give the instance its own security group
    SSH_ACCESS_NOT_SUPPORTED_IN_ZONE409Not available for VPC instances yet
    SECURITY_GROUPS_NOT_SUPPORTED_IN_ZONE409VPC instances use firewall rules
    DEFAULT_SECURITY_GROUP_UNDELETABLE409Edit its rules instead
    FIREWALL_RULES_NOT_SUPPORTED409Firewall rules are for VPC subnets
    NETWORK_NAME_TAKEN409Choose another name
    NETWORK_NOT_READY409Wait for the VPC to be active
    NETWORK_HAS_INSTANCES409Delete its instances first
    NETWORK_HAS_PUBLIC_IPS409Release its public IPs first
    SUBNET_HAS_KUBERNETES_CLUSTERS409Delete the Kubernetes clusters in the subnet first
    PUBLIC_IP_NOT_FOR_PORT_FORWARDING409Use a port_forwarding address
    PUBLIC_IP_NOT_STATIC_NAT409Only a static_nat address can be attached or detached; change a port forwarding address's rules, or a load balancer's targets, instead
    PUBLIC_IP_HAS_PORT_FORWARDS409Delete its rules first
    PUBLIC_IP_HAS_LOAD_BALANCERS409Delete the address's load balancers first
    INSTANCE_BEHIND_LOAD_BALANCER409Remove the instance from its load balancers' targets first
    PORTS_IN_USE409Another rule forwards these ports
    SNAPSHOT_NAME_TAKEN409Choose another name
    SECURITY_GROUP_NAME_TAKEN409Choose another name
    SSH_KEY_NAME_TAKEN409Choose another name
    SSH_KEY_ALREADY_EXISTS409The key is already registered
    SNAPSHOT_SCHEDULE_NOT_FOUND404No schedule is set; PUT one
    PROVISIONING_UNAVAILABLE503Retry with backoff
    CONSOLE_UNAVAILABLE503Retry shortly
    OPERATION_STREAM_UNAVAILABLE, OPERATION_STREAM_TIMEOUTeventThe operation's event stream ended; reconnect, or poll the operation
    SECURITY_GROUP_ATTACHED_TO_DATABASE409Detach the group from the database named in detail, then delete it
    INSTANCE_NOT_SETTLED409Wait until the instance is running or stopped with nothing else in progress

    Database codes

    The database endpoints have codes of their own, with a page that explains each one: database error codes. In short:

    codeStatusWhat to do
    DATABASE_NOT_FOUND, DATABASE_ORDER_NOT_FOUND, DATABASE_SNAPSHOT_NOT_FOUND404Check the ids; a snapshot is found only under its own database
    DATABASE_NAME_TAKEN, DATABASE_SNAPSHOT_NAME_TAKEN409Choose another name
    DATABASE_NOT_RUNNING409Start the database first (password changes and storage resizes need it running)
    DATABASE_NOT_STOPPED409Stop the database first
    DATABASE_SNAPSHOT_NOT_READY409Wait until the database is running or stopped
    DATABASE_STORAGE_RESIZE_IN_PROGRESS409Wait for the resize in flight to finish
    DATABASE_ACCESS_RANGE_LIMIT_EXCEEDED422Keep rules plus security-group ranges to 1,024
    DATABASE_HOSTNAME_UNAVAILABLE503Retry with a new Idempotency-Key
    DATABASE_STORAGE_UNAVAILABLE503Storage is not offered in that zone yet; try later
    DATABASES_UNAVAILABLE503Databases are unavailable right now; try later

    Kubernetes codes

    The managed Kubernetes endpoints have codes of their own; the guide's troubleshooting explains each, field codes included. In short:

    codeStatusWhat to do
    KUBERNETES_CLUSTER_NOT_FOUND404Check the cluster id (k8s_…). A deleted cluster answers this at once, although its nodes are destroyed 12 hours later
    KUBERNETES_CLUSTER_NAME_TAKEN409Choose another name
    KUBERNETES_CLUSTER_LIMIT409Delete a cluster, or contact support to raise the limit
    KUBERNETES_CLUSTER_NOT_RUNNING409Start the cluster first; scaling, autoscaling, API server access and upgrades need it running
    KUBERNETES_CLUSTER_BUSY409Wait until the cluster is running or stopped
    KUBERNETES_CLUSTER_NOT_CHANGEABLE409It is stopped, being deleted, or failed
    KUBECONFIG_UNAVAILABLE409Wait until the cluster is running
    KUBERNETES_UNAVAILABLE503Managed Kubernetes is not open on the platform yet

    Private network codes

    From adding a private database network interface to a standard instance:

    codeStatusWhat to do
    SECURITY_GROUP_ALLOWS_PRIVATE_NETWORK409Narrow the rules named in detail so none admits 10.250.0.0/20, ICMP included
    PRIVATE_NETWORK_NOT_AVAILABLE409Only standard instances in af-abj-1 can have one
    PRIVATE_NETWORK_ALREADY_ATTACHED409It already has one; read private_network_ip
    PRIVATE_NETWORK_NOT_ATTACHED409It has none to remove
    PRIVATE_NETWORK_CHANGE_IN_PROGRESS409Follow the attach or detach already running

    Field codes

    These appear inside errors on a 422, each with the field it is about.

    codeTypical fieldMeans
    REQUIREDanyThe field is missing
    UNKNOWN_FIELDanyNot a field of this request
    PLAN_NOT_FOUNDplan_slugNot an active plan
    PLAN_NOT_BIGGERplan_slugResize needs a bigger plan
    IMAGE_NOT_FOUNDimage_slugNot an active image
    IMAGE_NOT_AVAILABLE_IN_ZONEimage_slugNot offered where this instance runs
    ENCRYPTION_NOT_SUPPORTEDencryptedencrypted is true, but this image has no encrypted version available to your organization
    ENCRYPTION_CONFLICTencryptedencrypted is false, but image_slug is already an encrypted image
    SSH_KEY_NOT_FOUNDssh_key_idNot a key on this account
    REGION_NOT_AVAILABLEregionNot available for this resource
    SUBNET_REQUIREDsubnet_idNeeded when network_id is set
    SUBNET_NOT_FOUNDsubnet_idNot a subnet on this account
    SUBNET_NOT_IN_NETWORKsubnet_idNot in network_id
    SUBNET_NOT_USABLEsubnet_idBeing deleted or failed
    SECURITY_GROUP_NOT_FOUNDsecurity_group_idNot a group on this account
    CONFIRM_NAME_MISMATCHconfirm_nameNot the instance's current name
    DISK_OFFERING_NOT_FOUNDdisk_offering_slugNot an active offering
    SIZE_REQUIREDsize_gbNeeded for a custom-size offering
    INVALID_SIZEsize_gbMust be a whole number of GB
    INSTANCE_NOT_FOUNDinstance_idNot an instance on this account
    INSTANCE_NOT_RUNNINGinstance_idMust be running
    INSTANCE_WRONG_ZONEinstance_idMust be in the volume's zone
    INSTANCE_NOT_IN_NETWORKinstance_idMust be in the address's VPC
    NOT_ALLOWEDinstance_idNot taken here
    INVALID_MOUNT_POINTmount_pointMust be an absolute path
    INVALID_RULE_NUMBERnumberMust be 100–9999
    RULE_NUMBER_TAKENnumberUsed by another rule
    INVALID_PORTSport_startPorts invalid for the protocol
    INVALID_FIREWALL_RULEprotocolDirection, protocol or action invalid
    PURPOSE_NOT_AVAILABLEpurposeNot available yet
    INVALID_SSH_PUBLIC_KEYpublic_keyNot an OpenSSH public key
    INVALID_NAME, NAME_TOO_LONGname1–255 characters
    INVALID_METRIC_INTERVALintervalOne of 1h, 24h, 7d, 30d
    INVALID_PERIODperiodOne of 30d, 7d, month, last_month
    INVALID_PLACEMENTplacementstandard or vpc
    UNSUPPORTED_CURRENCYcurrencyNGN or USD
    INVALID_MACHINEmachinesA line in the estimate is invalid
    TOO_MANY_MACHINESmachinesAt most 50 lines
    INVALID_DATABASE_NAMEname1–255 characters
    INVALID_DATABASE_ENGINEenginepostgresql, mysql or mariadb
    INVALID_DATABASE_VERSIONversionNot an offered version line
    INVALID_DATABASE_ZONEzone_idNot a zone you can use
    DATABASE_VERSION_NOT_AVAILABLE_IN_ZONEzone_idThat version is not offered in that zone
    DATABASE_SUBNET_REQUIRED, DATABASE_SUBNET_NOT_ALLOWEDsubnet_idRequired in af-abj-2, refused in af-abj-1
    DATABASE_SUBNET_NOT_FOUND, DATABASE_SUBNET_WRONG_ZONE, DATABASE_SUBNET_NOT_USABLEsubnet_idNot a usable subnet of yours in zone_id
    INVALID_DATABASE_ADMIN_USERNAMEadmin_username3–32 lowercase letters, digits, underscores; not reserved
    INVALID_DATABASE_PASSWORDpassword16–128 printable characters, no spaces, quotes or backslashes
    INVALID_DATABASE_STORAGEstorage_gbPlan's size to 2,000 GB, in 10 GB steps; a resize must grow
    INVALID_DATABASE_SNAPSHOT_NAMEname1–255 characters
    INVALID_ACCESS_RULEaccess_rulesAn IPv4 CIDR no wider than /8, never 0.0.0.0/0
    TOO_MANY_ACCESS_RULESaccess_rulesAt most 50
    DUPLICATE_ACCESS_RULEaccess_rulesEach CIDR once
    INVALID_DATABASE_SECURITY_GROUPSsecurity_group_idsAt most 5, each once
    DATABASE_SECURITY_GROUP_NOT_FOUND, DATABASE_SECURITY_GROUP_WRONG_ZONE, DATABASE_SECURITY_GROUP_NOT_USABLEsecurity_group_idsYour own usable groups in the database's zone
    RULE_ALLOWS_PRIVATE_NETWORKrulesAn instance on this group has a private network interface; leave 10.250.0.0/20 out
    SECURITY_GROUP_ALLOWS_PRIVATE_NETWORKsecurity_group_idThe instance has a private network interface; pick a group that admits nothing from 10.250.0.0/20
    DATABASE_ACCESS_RANGE_LIMIT_EXCEEDEDrulesAn attached database would get more than 1,024 ranges
    INVALID_KUBERNETES_WORKER_COUNTworkers1 to 10
    INVALID_KUBERNETES_AUTOSCALINGautoscalingmin_workers and max_workers 1 to 10, minimum no more than maximum, workers within them; no workers while autoscaling is on
    INVALID_API_ALLOWED_CIDRSapi_allowed_cidrsAt most 20 IPv4 ranges, like 203.0.113.0/24
    API_ALLOWED_CIDRS_VPC_ONLYapi_allowed_cidrsOnly clusters in a VPC zone can limit API server access

    When an operation fails

    An accepted change (202) can still fail later. Its operation then ends failed, and its failure says why:

    JSON
    {
      "id": "op_…",
      "kind": "attach_private_network",
      "status": "failed",
      "failure": {
        "code": "SECURITY_GROUP_ALLOWS_PRIVATE_NETWORK",
        "reason": "The instance's security group was changed to allow 10.250.0.0/20 before the interface was added. Narrow it, then try again."
      }
    }

    Branch on failure.code, such as DATABASE_STORAGE_GROW_FAILED or INSTANCE_PRIVATE_NETWORK_ATTACH_FAILED; show failure.reason, whose wording can change. The resource is left as it was before. These are listed with the guide for each feature, for example the database error codes. Retry a failed operation with a new Idempotency-Key: the old one replays the failure.

    A change the platform itself could not carry out (creating, starting or resizing a machine, for example) fails with one of these codes, whatever the resource:

    failure.codeMeansWhat to do
    PROVISIONING_CAPACITY_UNAVAILABLENo capacity for it in the zone right nowTry a different plan or zone, or try again later
    PROVISIONING_LIMIT_EXCEEDEDYour account reached its limit for this kind of resource. A Kubernetes cluster or scale counts every node it could have, up to its autoscaling maximum, and fails before anything is createdDelete what you no longer use, ask for less, or contact support to raise the limit
    PROVISIONING_ADDRESSES_EXHAUSTEDNo free addresses in the zone right nowTry again later, or choose another zone
    PROVISIONING_IMAGE_UNAVAILABLEThe image is not available in this zone right nowChoose another image or zone, or try again later
    PROVISIONING_RESOURCE_BUSYThe resource was busy with another changeWait for it to settle, then retry
    PROVISIONING_RESOURCE_CONFLICTA resource with these settings already existsUse a different name or settings
    PROVISIONING_RESOURCE_NOT_FOUNDThe resource no longer exists on the platformRefresh, then retry
    PROVISIONING_INVALID_REQUESTA setting is not valid hereCheck the request, then retry
    PROVISIONING_UNAVAILABLEThe platform is temporarily unavailableRetry in a few minutes
    PROVISIONING_INTERNAL_ERRORSomething failed on our side; we have been alertedRetrying will not help; contact support with the operation id
    PROVISIONING_FAILEDThe change could not be completedRetry; contact support with the operation id if it keeps failing

    New codes may be added within v1. Treat an unknown code by its status.

    Was this page helpful?

    Updated