Skip to content

Error Handling & Exit Codes

Neil Martin edited this page Apr 16, 2026 · 4 revisions

Error Handling & Exit Codes

Exit Codes

Code Name Meaning
0 success Command completed successfully
1 general General error (network failure, unexpected error)
2 usage Invalid usage (bad flags, missing required args)
3 authentication Authentication failed (invalid credentials, expired token)
4 not_found Resource not found
5 permission_denied Insufficient privileges
6 rate_limited Rate limited by server

HTTP Status Mapping

The CLI maps HTTP error responses to specific exit codes:

HTTP Status Exit Code Description
401 Unauthorized 3 (authentication) Invalid or expired credentials
403 Forbidden 5 (permission_denied) Account lacks required API privileges
404 Not Found 4 (not_found) Requested resource does not exist
429 Too Many Requests 6 (rate_limited) Server throttling requests
Other 4xx/5xx 1 (general) Generic server error

Structured JSON Errors

When -o json is active, errors are emitted as JSON on stdout instead of plain text on stderr. This keeps jq pipelines and AI agent integrations working even on failure.

{
  "error": "authentication",
  "message": "authentication failed (HTTP 401): ...",
  "exitCode": 3
}

The error field maps to: general, usage, authentication, not_found, permission_denied, rate_limited.

Non-JSON output formats retain the default behavior (plain text on stderr).

HTTP Retry Logic

The CLI automatically retries failed requests with exponential backoff:

Attempt Delay
1st retry 1 second
2nd retry 2 seconds
3rd retry 4 seconds

Retries occur for:

  • Network errors — connection refused, timeout, DNS failure
  • 429 Too Many Requests — respects Retry-After header when present

After 3 retries:

  • Network errors → exit code 1 (general)
  • Rate limiting → exit code 6 (rate_limited)

Non-retryable errors (401, 403, 404, other 4xx) fail immediately without retrying.

Using Exit Codes in Scripts

#!/bin/bash

# Check exit code directly
jamf-cli pro computers get 42 -o json --no-input > /tmp/computer.json 2>/dev/null
case $? in
  0) echo "Success" ;;
  3) echo "Auth failed — run: jamf-cli config validate" ;;
  4) echo "Computer 42 not found" ;;
  5) echo "Permission denied — check API role privileges" ;;
  6) echo "Rate limited — wait and retry" ;;
  *) echo "Unexpected error" ;;
esac

# Guard clause pattern
jamf-cli pro computers get 42 -o json --no-input > /tmp/computer.json 2>/dev/null || {
  echo "Failed to fetch computer (exit code $?)"
  exit 1
}

# JSON error handling
result=$(jamf-cli pro computers get 42 -o json --no-input 2>/dev/null)
if [ $? -ne 0 ]; then
  echo "$result" | jq -r '.message'
  exit 1
fi

Error Messages

Error messages include actionable suggestions where possible:

Error Suggestion
authentication failed (HTTP 401) Check your credentials with: jamf-cli config validate
permission denied (HTTP 403) The authenticated account lacks the required API privileges.
resource not found (HTTP 404) Shows the method and path that failed
rate limited (HTTP 429) Wait a moment and try again.
no token configured Provide one via JAMF_TOKEN env var or a config profile
server URL is required Use --url, JAMF_URL env var, or jamf-cli config add-profile

jamf-cli Wiki


Products

  • Jamf Pro — jamf-cli pro
  • Jamf Platform API — jamf-cli pro (platform commands)
  • Jamf Protect — jamf-cli protect
  • Jamf School — jamf-cli school

Clone this wiki locally