-
Notifications
You must be signed in to change notification settings - Fork 2
Error Handling & Exit Codes
Neil Martin edited this page Apr 16, 2026
·
4 revisions
| 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 |
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 |
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).
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-Afterheader 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.
#!/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
fiError 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 |
Repository · Issues · Releases
jamf-cli Wiki
- Home
- Community
- Getting Started
- CLI Reference
- Product Commands
- Workflows
- Configuration
- Reference
Products
- Jamf Pro —
jamf-cli pro - Jamf Platform API —
jamf-cli pro(platform commands) - Jamf Protect —
jamf-cli protect - Jamf School —
jamf-cli school