Skip to content
HTTP errors in web scraping and automation · error message

HTTP: 403 Forbidden

Policy / accountHTTP 403Access and blocking (401, 403, 407, 451)

Last verified

The exact message
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://example.com/page

What it means

A 403 means the server understood the request and decided not to serve it. Unlike a 401, sending credentials will not change the answer by itself: the server has made a policy decision about this client, this path or this request. RFC 9110 lets a server explain why in the body, but many sites send only a generic block page.

When a page opens fine in your browser but a script gets 403, the difference is almost always something the site measures about the client: the request rate, the IP range it comes from (cloud and data-center ranges are often treated differently from home connections), missing cookies from an earlier page, or a policy that only admits interactive browsers. A firewall or bot-management layer often issues it before the request reaches the application.

What is not wrong: the URL usually exists and the server is up. A 403 is the site telling you it does not want this client to have this resource, which is a signal to change approach rather than to retry harder.

What it looks like

import requests

r = requests.get("https://example.com/page", timeout=30)
print(r.status_code)            # 403
print(r.headers.get("server"))  # e.g. cloudflare
print(r.text[:500])             # block page names the reason
r.raise_for_status()
# requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://example.com/page

Why it happens

  • The site's terms or robots.txt disallow automated access to that path, and a firewall rule enforces it.
  • Too many requests from one IP in a short window triggered a block that is reported as 403 rather than 429.
  • Requests come from a cloud or data-center IP range the site's security rules treat as non-human traffic.
  • The resource needs a session (login, consent cookie, CSRF token) that the script never obtained.
  • Directory listing or the file itself is restricted by server configuration, regardless of who asks.

How to fix it

  1. Read the response body and headers; a CDN block page (Cloudflare, Akamai, AWS WAF) names itself and often includes a reference ID.
  2. Check robots.txt and the site's terms. If the path is disallowed, stop and look for an official API, data export or feed instead.
  3. If you have a legitimate need, contact the site owner with the reference ID and ask for access or an allowlist.
  4. If the content requires your own login, authenticate the way the site documents (API key, OAuth) instead of replaying browser cookies.
  5. Slow down to a modest, steady request rate and cache responses so you never fetch the same page twice.
  6. Treat a persistent 403 as the final answer for that resource.

How to stop it recurring

Start every scraping project by reading robots.txt, the terms of service and any published API. Identify your client honestly with a descriptive User-Agent and contact address, keep request rates low and steady, and cache aggressively. If a site uses Cloudflare, the block usually appears as error 1020; rate-based blocks often arrive first as 429. Treat repeated 403s as a request to stop, not an obstacle.

Official documentation: developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/403. See all HTTP error messages.

Related errors

Definitions

Quick answers

What does "403 Forbidden" mean in HTTP?

A 403 means the server understood the request and decided not to serve it. Unlike a 401, sending credentials will not change the answer by itself: the server has made a policy decision about this client, this path or this request. RFC 9110 lets a server explain why in the body, but many sites send only a generic block page.

How do I fix "403 Forbidden"?

1. Read the response body and headers; a CDN block page (Cloudflare, Akamai, AWS WAF) names itself and often includes a reference ID. 2. Check robots.txt and the site's terms. If the path is disallowed, stop and look for an official API, data export or feed instead. 3. If you have a legitimate need, contact the site owner with the reference ID and ask for access or an allowlist. 4. If the content requires your own login, authenticate the way the site documents (API key, OAuth) instead of replaying browser cookies. 5. Slow down to a modest, steady request rate and cache responses so you never…

Retries and timeouts without writing the loop

Autonoly's HTTP Request node and browser steps have per-node retries, timeouts and continue-on-fail, so a transient 429 or 503 can back off instead of failing the run. It has no proxies or IP rotation: if a site blocks automated traffic, that block applies to Autonoly too.

Also see Error handling in workflows.