Skip to main content
PacketMentor logo
Open menu
← All topics
Automation & Programmability Foundational

Troubleshoot REST APIs: Reading the Error

The decision tree for every bad REST response: start at the status code, read the body, check the request shape, isolate with curl. Covers Cisco CCNAAUTO 2.5.

Quick summary
  • Status code first digit tells you WHO: 4xx is you, 5xx is them, 3xx is a redirect, 2xx is fine.
  • Then read the error body. 90% of 4xx responses explain what you did wrong in plain English JSON.
  • If curl works and Python does not, add print(r.request.headers) and compare. Usually a missing header or wrong body encoding.

Mental model

Cisco objective 2.5 says “Troubleshoot a problem given the HTTP response code, request and API documentation”. There is a repeatable 4-step decision tree.

  1. Status code first digit.

    • 2xx → it worked. Not a bug.
    • 3xx → follow Location (curl -L does this).
    • 4xx → you sent something wrong. Read the body.
    • 5xx → server failed. Retry; if it persists, open a support ticket.
  2. Read the error body. Modern APIs return JSON with an error, errors, message, or detail field. The text usually points directly at the problem.

  3. Isolate. If a Python script fails, redo the same call in curl. If curl works, the bug is in your Python. If curl also fails, the bug is in the request.

  4. Compare working vs broken. Diff a request you know works against the one that fails. Nine times out of ten it is one header, one typo in a key, or wrong URL.

Status-code-by-status-code checklist

400 Bad Request

  • Malformed JSON (missing closing brace, trailing comma).
  • Required field missing.
  • Field type wrong (string instead of int).
  • Field value out of range.

Fix: read the body; it names the field. If you cannot see the body, retry with curl -i to show it.

401 Unauthorized

  • No Authorization header.
  • Wrong credentials.
  • Token expired.
  • Spelling: Authorization not authorization (most servers do not care; some do).

Fix: add / correct auth. For Bearer tokens, refresh if expired. See REST API auth.

403 Forbidden

  • Auth was accepted but your account has no permission for this resource.
  • Common on multi-tenant APIs: you authenticated as org A but asked about org B.

Fix: ask the admin for a wider scope, or use the right tenant / org id.

404 Not Found

  • Typo in the URL (devices vs device, trailing slash difference).
  • Resource id does not exist (deleted, or wrong id).
  • Some APIs return 404 instead of 403 for security — “we are not telling you if it exists”.

Fix: double-check URL. List the parent resource (GET /devices) to confirm the id you are asking about actually exists.

405 Method Not Allowed

  • You used GET on an endpoint that only supports POST, or vice versa.

Fix: check the docs for the endpoint and change -X.

409 Conflict

  • You tried to create something that already exists.
  • You tried to update a resource that has changed since you fetched it (optimistic concurrency).

Fix: GET first to see current state; use PUT or PATCH; include If-Match if the API supports ETags.

413 Payload Too Large

  • Request body exceeds the server’s limit (usually 1 to 10 MB).

Fix: split the work. Upload files in chunks. Batch creates smaller.

422 Unprocessable Entity

  • JSON parsed but failed validation (e.g., email field has no @, VLAN id is 5000).

Fix: read the body; adjust the field value.

429 Too Many Requests

  • Rate limit.

Fix: honor Retry-After. See API constraints.

500 Internal Server Error

  • Server bug or transient failure.

Fix: retry once after a few seconds. If persistent, open a vendor support ticket with the request id if the response headers include one.

502 Bad Gateway / 503 Service Unavailable / 504 Gateway Timeout

  • Problem between you and the application: a proxy, a load balancer, or a downstream the server depends on.

Fix: retry with exponential backoff.

Working methodology

Step 1 — reproduce in curl

If your Python script fails, build the exact same request in curl. Any random editor, no code, just:

curl -i -v -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"sw3","ip":"10.0.0.3"}' \
  https://api.example.com/devices

Step 2 — read everything

  • Status line.
  • All response headers (-i or -v).
  • Body.
  • If verbose, your request headers (prefixed > in curl -v).

Step 3 — binary-chop the request

Comment out one header, retry. Change one field, retry. Narrow until you find the single change that flips 4xx into 2xx.

Step 4 — fix in Python

Transliterate the working curl back to requests. The gotchas:

  • data= vs json=. Use json= for a dict; data= for a string.
  • Headers Python adds automatically (User-Agent, Content-Length).
  • Trailing slash on the URL — some APIs care.
  • URL encoding of query params — use params= dict, not string concatenation.

Step 5 — add resilience

Once the request works, add:

  • r.raise_for_status() so you fail loud on 4xx/5xx.
  • timeout=5 so hangs become errors.
  • Retry on 429 and 5xx with exponential backoff.
  • Log the response id (if the API returns one) so vendor support can trace.

Common gotchas

  • Content-Type: application/json missing. Python requests.post(..., json=...) sets it automatically; manual -d with curl does not.
  • Base URL has a region. Meraki, Catalyst Center and Webex have per-region API hostnames. Wrong region → 401 or 404.
  • Trailing slash. /devices vs /devices/ vary by API.
  • Capitalisation of JSON keys. deviceId vs deviceid matters.
  • Dates and timezones. API often wants ISO 8601 UTC (2026-10-03T12:34:56Z), not a local-time string.

FAQ

My script works in dev but fails in CI. Compare env vars. CI often has a different API key, a different token, or missing certificates.

I get 200 but the body is empty. Check Content-Length. If it is 0, the API did succeed but has nothing to return (common for DELETE and no-op PATCH). If the body should have content, check the Accept header you sent.

502 Bad Gateway immediately on every call. Usually a load balancer / proxy issue, not the API. Check the vendor status page.

Why does my 401 become 200 after a few minutes? Clock skew on your machine. TLS cert validation and OAuth tokens can fail if your clock is off by more than a few minutes.

Master this on a real network

Want this drilled into reflex?

1:1 weekly sessions, live feedback on your labs, and US interview prep: built around the CCNA Automation® exam blueprint. Free first session. No card on file until you decide.

Claim my free session →

Get the free CCNA 12-week roadmap

You're already reading up on Troubleshoot REST APIs: Reading the Error. The roadmap is the order I recommend studying every CCNA topic in: with what to lab each week and where Troubleshoot REST APIs: Reading the Error fits. A written personal reply, not an autoresponder. Expect it within one business day.

Personal reply from a senior network engineer. No third-party tracking. Unsubscribe any time.