Ana içeriğe geç

Guides / fix

Access denied on this server: causes and fixes

"Access denied on this server" means the server received your request, understood it, and refused to serve it. The page exists and the machine is up. Something between the request and the file decided you are not allowed to have it, and it almost always carries HTTP status 403.

What the error means

The wording is not part of any standard, which is why it shows up in so many different shapes. Apache prints it from a directory rule. ModSecurity and hosting control panels print it when a rule fires. A CDN or WAF prints its own branded version with a reference number. AWS returns it as a short XML document from S3 or CloudFront. All of them are saying the same thing at the HTTP level: 403, refused, and no invitation to try again with credentials.

That last part separates it from the errors it gets confused with. A 401 asks you to authenticate and expects a retry. A 404 says the resource is not there. A 403 says the resource is there and you are not getting it, and repeating the request unchanged will produce the same answer. The status itself is covered in 403 Forbidden; this guide is about working out which layer said no.

Start by finding out whether it is you or everyone, because the fixes have nothing in common. If a colleague on another network loads the page fine, you are blocked. If nobody can load it, the site is misconfigured.

Why it happens

  • Your IP address is blocked. A firewall or WAF rule added after failed logins, a scraper on your network, or a manual block that nobody removed.
  • Rate limiting. Too many requests in a short window, which is easy to trigger with a reload-heavy debugging session or a shared office connection.
  • Geographic restrictions. Sites limited to one country, or blocking a region wholesale after abuse from it.
  • A shared or reputation-flagged IP. VPN exit nodes, mobile carrier NAT and cheap hosting ranges are often blocked as a group for what other users did.
  • Bot rules reading your user agent. Command line tools, headless browsers and unusual user agent strings get refused where a normal browser is allowed.
  • Stale cookies or a broken session. An expired session token can produce a refusal rather than a redirect to the login page.
  • A browser extension stripping or adding headers, or a corporate proxy rewriting the request.
  • File and directory permissions. The web server user cannot read the file or traverse a parent directory.
  • No index file, with listings turned off. A directory request with nothing to serve and Options -Indexes in force returns 403 rather than an empty page.
  • An explicit deny rule. A Require all denied in Apache config or a leftover .htaccess from a maintenance window.
  • A WAF false positive. ModSecurity and similar rule sets refuse legitimate requests containing something that resembles an injection attempt, often in a form field or a query string.
  • Cloud storage permissions. An S3 bucket policy or a CloudFront origin access setting that does not permit the object to be read.

If you are the visitor

  1. Confirm the status code rather than trusting the page text. curl -s -o /dev/null -w "%{http_code}\n" https://example.com/page tells you whether this is really a 403 or a 401 or 429 wearing a similar message.
  2. Open the page in a private window. That drops cookies and most extensions in one step. Success there means the fix is on your profile, not the site.
  3. Clear cookies for that site specifically instead of clearing everything, then reload.
  4. Turn off the VPN or proxy and try again. If it then works, the exit node's address is what was refused, and switching to another region usually clears it.
  5. Try a different network, most easily a phone on mobile data. This is the fastest way to prove your address is the blocked thing.
  6. Disable extensions one at a time, starting with ad blockers, privacy tools and anything that edits headers.
  7. Check whether the block is regional by asking someone in another country, or by reading the block page for a mention of your location.
  8. Contact the site with the reference number if the block page shows one. WAF pages usually print an incident ID that lets the operator find the exact rule that fired in seconds.

If you own the site

  1. Read the error log first. It names the cause directly, and every step after this is guesswork without it:
    sudo tail -50 /var/log/apache2/error.log
    sudo tail -50 /var/log/nginx/error.log
    sudo grep -i modsecurity /var/log/apache2/error.log | tail -20
    Apache logs a permission problem as "client denied by server configuration" or "Permission denied". nginx logs "directory index of ... is forbidden" or "open() ... failed (13: Permission denied)". Those three messages cover most cases.
  2. Check permissions along the whole path, including every parent directory. A directory the web server cannot enter refuses everything below it, however correct the file itself looks:
    namei -l /var/www/html/index.html
    sudo chmod 755 /var/www/html
    sudo chmod 644 /var/www/html/index.html
    sudo chown -R www-data:www-data /var/www/html
  3. Look for a deny rule in the vhost and in every .htaccess under the document root. sudo grep -rn "Require\|Deny from" /etc/apache2/sites-enabled /var/www/html finds them in one pass.
  4. Add an index file or enable listing if the request is for a directory. Serving 403 for a bare directory is the default, not a fault.
  5. Check SELinux on Red Hat family systems, where correct Unix permissions are still not enough: ls -Z /var/www/html, then sudo restorecon -Rv /var/www/html.
  6. Find the WAF rule that fired and either fix the request or add a narrow exception for that rule and that path. Turning the rule set off entirely to make the error go away trades one problem for a worse one.
  7. Review the block list for ranges added during an incident. Temporary blocks that were never given an expiry are a common cause of complaints weeks later.
  8. For S3 or CloudFront, check the bucket policy and the origin access configuration. The XML body names the operation that was refused, which points at the specific permission to grant.

Check it from outside

A refusal aimed at one address looks exactly like a site-wide outage from that address, and you cannot tell the two apart from the machine that is being refused. Ask from somewhere else.

The response headers usually name the layer that answered. Look at Server, and at vendor headers such as CF-Ray or X-Amz-Cf-Id, which tell you whether the refusal came from your origin or from an edge that never reached it:

curl -sS -D - -o /dev/null https://example.com/page
curl -s -o /dev/null -w "%{http_code}\n" -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" https://example.com/page

If the second command returns 200 where the first returned 403, the block is on the user agent and nothing is wrong with your permissions. Then run the HTTP check against the same URL from checkpoints in several countries at once. A 403 from every location is a configuration problem on the site. A 403 from two countries and 200 from the rest is a geographic rule or a regional block list, which is a conclusion you cannot reach with one curl from one desk.

Catching a 403 you did not intend

Access rules break in ways that produce no error on your side. A WAF rule set updates, a certificate renewal script rewrites a config, a temporary block gets forgotten, and the site keeps returning 200 to you while refusing a slice of real visitors. Nothing in your own logs looks alarming, because a 403 is a normal, successful refusal as far as the server is concerned. A scheduled check that reads the status code from 300+ checkpoints in 158 cities catches the day a region starts getting refused, and alerts by email, SMS, voice call, Slack, Telegram and more. The other guides here are in the fix cluster, and the status code behind this message has its own reference in 403 Forbidden.

Check it now

Run the free check against your own site - no account needed.

HTTP check

Monitor this permanently

Get alerted the moment it breaks: HostTracker checks from 300+ locations and notifies you by email, SMS, Slack, Telegram and more.

HostTracker features