agentsclimarketplace

Oraclecloud common errors

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/oraclecloud-pack/skills/oraclecloud-common-errors

'Diagnose and fix Oracle Cloud Infrastructure API errors with real error codes and proven fixes.From its SKILL.md

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill oraclecloud-common-errors

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

10.7 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it

Oracle Cloud Common Errors

Overview

OCI API errors are notoriously cryptic. NotAuthorizedOrNotFound (404) could mean an IAM policy is missing or you typed the OCID wrong — the error is intentionally ambiguous for security. NotAuthenticated (401) covers six different config file problems. CERTIFICATE_VERIFY_FAILED has different fixes depending on your SDK language, OS, and whether you are behind a corporate proxy.

Purpose: A diagnostic decoder ring mapping every common OCI error to its real root cause and fix, with runnable diagnostic commands for each scenario.

Prerequisites

  • An OCI account with ~/.oci/config configured (see oraclecloud-install-auth)
  • Python 3.8+ with pip install oci installed
  • OCI CLI installed (pip install oci-cli) for diagnostic commands

Instructions

Authentication Errors (401 NotAuthenticated)

The 401 error has six distinct root causes. Run this diagnostic to isolate which one:

import oci
import os

def diagnose_auth():
    """Diagnose OCI 401 NotAuthenticated errors."""
    config_path = os.path.expanduser("~/.oci/config")

    # Check 1: Config file exists
    if not os.path.exists(config_path):
        return "CAUSE: Config file missing. Run: oci setup config"

    config = oci.config.from_file(config_path)

    # Check 2: All required fields present
    required = ["user", "fingerprint", "tenancy", "region", "key_file"]
    for field in required:
        if field not in config or not config[field]:
            return f"CAUSE: Missing field '{field}' in ~/.oci/config"

    # Check 3: Key file exists
    key_path = os.path.expanduser(config["key_file"])
    if not os.path.exists(key_path):
        return f"CAUSE: Key file not found: {key_path}"

    # Check 4: Key is private (not public)
    with open(key_path, "r") as f:
        first_line = f.readline().strip()
    if "PUBLIC" in first_line:
        return "CAUSE: key_file points to PUBLIC key. Use the private key (no _public suffix)"

    # Check 5: Key file permissions
    perms = oct(os.stat(key_path).st_mode)[-3:]
    if perms != "600":
        return f"CAUSE: Key permissions are {perms}. Run: chmod 600 {key_path}"

    # Check 6: Fingerprint matches
    return "Config looks valid. Fingerprint mismatch? Verify in Console > User Settings > API Keys"

print(diagnose_auth())

401 Root Cause Table:

SymptomRoot CauseFix
did not find a proper configuration for userMissing or malformed ~/.oci/configRecreate with oci setup config
could not find private keykey_file path wrong or file missingCheck path; key must exist at that location
private key does not matchFingerprint in config does not match uploaded public keyUpload correct public key or regenerate pair
key_file points to public keykey_file=~/.oci/oci_api_key_public.pemChange to key_file=~/.oci/oci_api_key.pem (private key)
permission denied reading keyKey file permissions too openchmod 600 ~/.oci/oci_api_key.pem
InvalidKeyIdUser OCID or tenancy OCID wrongVerify OCIDs in Console > Profile > User Settings

Authorization Errors (404 NotAuthorizedOrNotFound)

This is the most confusing OCI error. A 404 means either the resource does not exist or you lack IAM permission to see it. OCI hides the distinction intentionally.

Diagnostic steps:

# Step 1: Verify the OCID format is correct
echo "ocid1.instance.oc1.iad.aaaa..." | grep -P '^ocid1\.\w+\.oc1\.'

# Step 2: Verify you can list resources in the compartment
oci compute instance list --compartment-id <COMPARTMENT_OCID> --limit 1

# Step 3: Check IAM policies affecting your user
oci iam policy list --compartment-id <TENANCY_OCID> --all \
  --query "data[?contains(statements[0], 'instances')]"

Common IAM policy fixes:

# Allow a group to manage compute in a compartment
allow group Developers to manage instances in compartment MyCompartment

# Allow a group to read all resources (useful for debugging)
allow group Developers to read all-resources in tenancy

SSL Certificate Errors (CERTIFICATE_VERIFY_FAILED)

# Diagnostic: check which CA bundle Python uses
import ssl
print(ssl.get_default_verify_paths())

# Fix 1: Install/update certifi
# pip install --upgrade certifi

# Fix 2: Point to system CA bundle (Linux)
import os
os.environ["REQUESTS_CA_BUNDLE"] = "/etc/ssl/certs/ca-certificates.crt"

# Fix 3: Corporate proxy — add proxy CA to certifi bundle
# cat proxy-ca.pem >> $(python -c "import certifi; print(certifi.where())")

SSL Fix by Environment:

EnvironmentFix
Linux (system Python)pip install --upgrade certifi
macOSbrew install ca-certificates + update certifi
Corporate proxyAdd proxy CA cert to certifi bundle
Docker containerCopy CA bundle: COPY ca-bundle.crt /etc/ssl/certs/
Air-gappedSet REQUESTS_CA_BUNDLE to local CA file

Rate Limit Errors (429 TooManyRequests)

OCI does not send a Retry-After header. You must implement your own backoff:

import oci
import time
import random

def handle_rate_limit(fn, max_retries=5):
    """Handle OCI 429 errors. No Retry-After header — use jittered backoff."""
    for attempt in range(max_retries):
        try:
            return fn()
        except oci.exceptions.ServiceError as e:
            if e.status == 429:
                delay = (2 ** attempt) + random.uniform(0, 2)
                print(f"Rate limited. Waiting {delay:.1f}s (attempt {attempt + 1})")
                time.sleep(delay)
            else:
                raise
    raise RuntimeError("Rate limit retries exhausted")

# Or use the built-in strategy
compute = oci.core.ComputeClient(
    config, retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY
)

Timeout Errors (ServiceError status -1)

A ServiceError with status == -1 means the SDK timed out before the server responded:

import oci

config = oci.config.from_file("~/.oci/config")

# Default has NO connection timeout. Always set both:
compute = oci.core.ComputeClient(
    config,
    timeout=(10, 60)  # (connect_timeout, read_timeout)
)

# Object Storage uploads need longer read timeout
object_storage = oci.object_storage.ObjectStorageClient(
    config,
    timeout=(10, 600)  # 10 min for large uploads
)

Internal Server Errors (500 InternalError)

import oci

# Check OCI service health first
# https://ocistatus.oraclecloud.com

# 500 errors are transient — use retry strategy
compute = oci.core.ComputeClient(
    oci.config.from_file("~/.oci/config"),
    retry_strategy=oci.retry.DEFAULT_RETRY_STRATEGY  # Retries 500, 502, 503, 504
)

Output

After working through this diagnostic guide you will have:

  • Identified the exact root cause of your OCI error from the error code and message
  • A runnable diagnostic script for 401 auth errors that checks all six failure modes
  • IAM policy statements to resolve 404 authorization errors
  • Correct timeout and retry configuration for 429 and 500 errors
  • SSL certificate fixes for your specific environment

Error Handling

Complete OCI Error Reference Table:

ErrorStatusExceptionRoot CauseFix
NotAuthenticated401ServiceErrorWrong config, key, or fingerprintRun diagnose_auth() above
NotAuthorizedOrNotFound404ServiceErrorMissing IAM policy OR wrong OCIDCheck OCID format, then IAM policies
TooManyRequests429ServiceErrorRate limit exceededBackoff with jitter (no Retry-After header)
InternalError500ServiceErrorOCI service errorRetry; check https://ocistatus.oraclecloud.com
Timeout-1ServiceErrorNo response in timeSet timeout=(connect, read) on client
CERTIFICATE_VERIFY_FAILEDSSLErrorCA bundle outdated or proxyUpdate certifi or set REQUESTS_CA_BUNDLE
InvalidParameter400ServiceErrorMalformed request bodyCheck OCID format and required fields
Out of host capacity500ServiceErrorNo hosts available (ARM shapes)Retry loop; see oraclecloud-hello-world

Examples

One-command connectivity test:

# Tests auth + network + SSL in one call
oci iam region list --output table 2>&1 || echo "FAILED — run oraclecloud-common-errors diagnostic"

Catch-all error handler for scripts:

import oci
import sys

config = oci.config.from_file("~/.oci/config")
compute = oci.core.ComputeClient(config)

try:
    compute.list_instances(compartment_id=config["tenancy"])
    print("OK")
except oci.exceptions.ServiceError as e:
    print(f"OCI Error: {e.status} {e.code}")
    print(f"Message: {e.message}")
    print(f"Request ID: {e.request_id}")  # Include this in support tickets
    if e.status == 401:
        print("ACTION: Check ~/.oci/config — see oraclecloud-install-auth")
    elif e.status == 404:
        print("ACTION: Verify OCID and IAM policies — see 404 section above")
    elif e.status == 429:
        print("ACTION: Rate limited — implement backoff")
    elif e.status == -1:
        print("ACTION: Timeout — increase client timeout values")
    sys.exit(1)
except oci.exceptions.ConfigFileNotFoundError:
    print("ACTION: ~/.oci/config not found. Run: oci setup config")
    sys.exit(1)

Resources

Next Steps

Once errors are resolved, see oraclecloud-sdk-patterns for retry and timeout patterns to prevent errors proactively, or oraclecloud-local-dev-loop for a productive development workflow with fast feedback.

What ships with it: 1 file

2.0 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.