Error Medic

Troubleshooting GitHub API Rate Limit (403/429), Timeout, and 401 Unauthorized Errors

Fix GitHub API 403 rate limits, 429 Too Many Requests, 401 Unauthorized, and timeout errors. Learn to check limit headers and implement robust retry logic.

Last updated:
Last verified:
1,409 words
Key Takeaways
  • HTTP 403 and 429 errors indicate you have hit either primary rate limits (e.g., 5,000 req/hr) or secondary abuse limits; always respect the 'Retry-After' or 'x-ratelimit-reset' headers.
  • HTTP 401 Unauthorized usually stems from an expired token, missing OAuth scopes, or an unconfigured SAML SSO authorization for your PAT.
  • HTTP 502 Bad Gateway and API timeouts are often caused by retrieving excessively large datasets without pagination or poorly optimized GraphQL queries.
  • To mitigate rate limiting permanently, migrate your CI/CD pipelines from Personal Access Tokens (PATs) to GitHub Apps, which offer dynamically scaling limits, and use ETags for conditional requests.
Authentication Methods & Rate Limit Comparison
MethodWhen to UseRate Limit QuotaRisk / Mitigation
UnauthenticatedQuick local testing, simple cURL scripts60 requests / hour / IPHigh risk of IP blocking. Only for trivial scripts.
Personal Access Token (PAT)Local dev, user-specific automation scripts5,000 requests / hourModerate. Tokens expire and are tied to a single user's lifecycle.
GitHub App InstallationEnterprise CI/CD, organization-wide automation15,000+ requests / hour (scales with org size)Lowest. Tokens are short-lived and permissions are granularly scoped.
GraphQL APIComplex data fetching, highly nested resource graphs5,000 points / hour (calculated by query complexity)High risk of 502/Timeout if the query depth and node count are unoptimized.

Understanding GitHub API Errors

When integrating with the GitHub API—whether building custom CI/CD pipelines, automating repository management, or extracting developer metrics—you will inevitably encounter rate limits and authentication errors. GitHub aggressively protects its infrastructure using primary and secondary rate limits. Understanding how to interpret headers like x-ratelimit-remaining and handle HTTP status codes (401, 403, 429, 502) is essential for building resilient automation systems.

1. HTTP 403 & 429: Primary and Secondary Rate Limits

GitHub's REST API enforces a strict rate limit. If you are unauthenticated, you are restricted to 60 requests per hour per IP address. Authenticated requests using a Personal Access Token (PAT) or OAuth token receive 5,000 requests per hour. GitHub Apps receive a dynamically scaling limit based on the size of the organization.

Primary Rate Limits (HTTP 403 Forbidden) When you exceed your primary quota, GitHub returns an HTTP 403 status code. The response body will contain a message indicating the rate limit was exceeded (API rate limit exceeded for user ID). Crucially, you must inspect the HTTP response headers to diagnose the issue:

  • x-ratelimit-limit: Your total allowed requests per hour.
  • x-ratelimit-remaining: The number of requests you have left in the current window.
  • x-ratelimit-reset: The time at which the current rate limit window resets in UTC epoch seconds.

Secondary Rate Limits (HTTP 429 Too Many Requests or 403) Secondary rate limits are abuse detection mechanisms. Even if you have thousands of requests remaining, you can trigger a secondary limit by:

  • Making too many concurrent requests.
  • Requesting data that is computationally expensive for GitHub to generate.
  • Mutating data (POST/PATCH/DELETE) too quickly.

When a secondary limit is hit, you will see an HTTP 429 or 403, accompanied by a Retry-After header. You must pause your requests for the number of seconds specified in this header. Failing to do so may result in an IP-level ban.

2. HTTP 401: Unauthorized Failures

An HTTP 401 response (Requires authentication) means the API token provided is missing, malformed, expired, or lacks the correct scopes to access the requested resource.

Common Root Causes for 401 Errors:

  • Expired Tokens: Classic PATs and Fine-Grained PATs often have strict expiration dates. Check your GitHub Developer Settings.
  • SAML SSO Enforcement: If your organization uses SAML Single Sign-On, a PAT must be explicitly authorized to access the organization. An unauthorized token will work for public repos but return a 401 or 404 for organizational repos.
  • Missing Scopes: The token does not have the necessary permissions (e.g., trying to read repo data with only user scopes).

3. HTTP 502 Bad Gateway and API Timeouts

Encountering an HTTP 502, 503, or a generic network timeout usually indicates an issue on GitHub's infrastructure, or that your query is too resource-intensive to execute within the designated time limit.

Why Timeouts Happen:

  • Massive Payloads: Querying an endpoint that returns a massive amount of data without pagination.
  • Complex GraphQL Queries: Highly nested GraphQL queries can exceed the maximum execution time of 10 seconds, resulting in a timeout.
  • GitHub Outages: Always check githubstatus.com to verify if the API is experiencing degraded performance.

Best Practices for Remediation

1. Implement Exponential Backoff with Jitter Never retry failed API requests in a tight loop. Implement an exponential backoff strategy. If you receive a 429 or 403 due to rate limiting, read the Retry-After or x-ratelimit-reset headers and sleep the executing thread until that time has elapsed. Add random jitter to avoid thundering herd problems.

2. Use Conditional Requests (ETags) GitHub API supports conditional requests to help you save your rate limit. When you make a request, GitHub returns an ETag header. On subsequent requests, include this value in the If-None-Match header. If the data hasn't changed, GitHub returns an HTTP 304 Not Modified, which does not count against your rate limit quota.

3. Migrate to GitHub Apps For enterprise automation and CI/CD pipelines, migrate away from Personal Access Tokens (PATs) and use a GitHub App. GitHub Apps have significantly higher rate limits (scaling with the organization size up to 15,000+ requests per hour) and provide short-lived, secure installation tokens.

4. Paginate Aggressively When interacting with REST endpoints that return arrays, use the per_page parameter (maximum 100) and follow the Link headers to navigate pagination safely without timing out the connection.

Frequently Asked Questions

bash
#!/bin/bash
# A robust bash script to interact with GitHub API, checking limits and handling rate limit headers
GITHUB_TOKEN="your_pat_here"
API_URL="https://api.github.com/repos/octocat/hello-world/issues"

# Function to check rate limit proactively
check_rate_limit() {
  local response=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/rate_limit)
  local remaining=$(echo "$response" | jq '.resources.core.remaining')
  local reset=$(echo "$response" | jq '.resources.core.reset')

  echo "Remaining requests: $remaining"
  if [ "$remaining" -le 5 ]; then
    local now=$(date +%s)
    local wait_time=$((reset - now + 5))
    echo "Rate limit critically low. Sleeping for $wait_time seconds..."
    sleep $wait_time
  fi
}

# Execute request and handle 403/429
fetch_data() {
  check_rate_limit
  local status_code=$(curl -s -o /tmp/response.json -w "%{http_code}" \
    -H "Authorization: Bearer $GITHUB_TOKEN" \
    -H "Accept: application/vnd.github.v3+json" \
    $API_URL)

  if [ "$status_code" -eq 200 ]; then
    echo "Success!"
    cat /tmp/response.json | jq '.[0].title'
  elif [ "$status_code" -eq 401 ]; then
    echo "Error 401: Unauthorized. Check your GITHUB_TOKEN and SSO permissions."
  elif [ "$status_code" -eq 403 ] || [ "$status_code" -eq 429 ]; then
    echo "Error $status_code: Rate limit or secondary abuse limit hit. Check Retry-After headers."
  elif [ "$status_code" -eq 502 ] || [ "$status_code" -eq 504 ]; then
    echo "Error $status_code: GitHub API timeout or Bad Gateway. Implementing backoff..."
    sleep 10
    fetch_data
  else
    echo "Unexpected HTTP status: $status_code"
  fi
}

fetch_data
E

Error Medic Editorial

Written by the Error Medic editorial team. We specialize in untangling complex infrastructure issues, API integrations, and CI/CD pipeline optimization for enterprise environments.

Sources

Related Guides