
401 Error: What It Means and How to Fix It
By Md. Sajid Sadman
July 31, 2026
Last Modified: July 31, 2026
You type in a password you are certain is correct, hit enter, and the page throws it straight back at you. No hint about what went wrong. Just a number: 401.
A 401 error means a web request lacks valid authentication credentials, and the server refuses access until you provide them. It usually stems from a wrong password, an expired token, or a missing authorization header.
The request itself arrived intact and the page exists. Identity is the only thing standing in the way.
This guide covers what the code means at the protocol level, why it is so often confused with a 403, and how to fix it whether you are a visitor, a WordPress site owner, or a developer chasing it down in an API call.
Key Takeaways
- A 401 error means the server could not verify your identity. Your request arrived intact and got rejected because the credentials were missing, expired, or wrong.
- Read it as “unauthenticated,” not “unauthorized.” Valid credentials fix a true 401. If the server knows you and still refuses, that is a 403.
- Check the WWW-Authenticate header first. Every compliant 401 carries it, and it usually names the exact failure before you change a thing.
- As a visitor, fix it fast: correct the URL, log back in, then clear your cached credentials and cookies.
- On WordPress, suspect a stripped Authorization header, a security plugin restricting the REST API, or a missing HTTPS requirement.
- On IIS, let the substatus code guide you. A 401.3 means file permissions, a 401.2 means a server auth mismatch, and each points to a different fix.
What Is a 401 Error?
A 401 error is an HTTP status code that means the server rejected the request because it lacks valid authentication credentials for the target resource.
The definition comes straight from the spec. RFC 9110, Section 15.5.2 states that the 401 status code indicates the request has not been applied because it lacks valid authentication credentials for the target resource. MDN describes it the same way: a request that was not successful because it lacks valid authentication credentials.
In plain terms, the server received your request and understood it perfectly. It simply refuses to act until you prove who you are. The resource exists, the URL resolved, and identity is the only thing standing in the way.
The naming trap that confuses even experienced developers
Here is the part almost every guide skips.
The status code is labeled “Unauthorized,” which sends a lot of people hunting for a permissions problem that does not exist.
A 401 is not about permission. It is about identity.
MDN draws the line cleanly: a 403 Forbidden is what you get when a request carries valid credentials and the client still lacks permission to perform the action. A 401 means the credentials were missing or invalid in the first place.
Read the code as “unauthenticated” rather than “unauthorized” and the confusion disappears. The misleading label is a historical artifact of the original HTTP specification, and it has been tripping up developers ever since.
That distinction changes how you fix it. If the server does not know who you are, sending valid credentials solves the problem. If the server knows exactly who you are and still says no, you are looking at a 403 and no amount of re-entering your password will help.
What a 401 response actually looks like
Most people only ever see the browser error page. Underneath it, the server sends something more useful.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm=”api.example.com”,
error=”invalid_token”,
error_description=”The access token expired”
Content-Type: application/json
That WWW-Authenticate header is the server’s challenge, and it is the single most useful line in the whole response.
It names the authentication scheme the server wants, such as Basic, Bearer, Digest, or NTLM, and it often carries an error description that tells you precisely what failed.
The spec treats this as mandatory.
RFC 9110 states that a server generating a 401 response MUST send a WWW-Authenticate header containing at least one challenge.
An API that returns a bare 401 with no challenge is technically non-compliant, and it leaves clients guessing between a missing token, an expired token, and a malformed header.
The many faces of a 401 error
The wording changes depending on the browser, server, and framework generating the response. The meaning underneath stays identical.
| What you see | Where it usually comes from |
|---|---|
| 401 Unauthorized | The standard status line, returned by most servers and APIs |
| Authorization Required | Apache, often behind .htpasswd protection |
| HTTP Error 401 | Chrome and Edge browser error pages |
| 401 Error: Access Denied | Custom application or framework error pages |
| HTTP 401 Unauthorized Error | API clients such as Postman and Insomnia |
| 401.1 to 401.5 | Microsoft IIS substatus codes that narrow the cause |
401 vs 403 vs 404: Telling the Codes Apart
Misreading these three sends you down the wrong troubleshooting path and wastes an afternoon. The table sorts them by what the server is really saying.
| Code | What the server is saying | Are you logged in? | Will credentials help? |
|---|---|---|---|
| 401 Unauthorized | I do not know who you are | No, or your credentials failed | Yes. Send valid credentials and retry |
| 403 Forbidden | I know who you are and the answer is still no | Yes, usually | No. You lack permission, not identity |
| 404 Not Found | I cannot find what you asked for | Not relevant | No. The resource is missing or hidden |
| 407 Proxy Auth Required | The proxy in front of me needs credentials | Not for the proxy | Yes, but for the proxy rather than the site |
A useful shortcut: 401 means “I do not know you,” 403 means “I know you and the answer is no,” and 404 Not Found means “I have no idea what you are asking for.”
There is a common API bug worth naming here. When the Authorization header is missing entirely, some APIs return a 403.
That is wrong, and it misleads clients into thinking they are authenticated but forbidden. A missing or invalid credential is always a 401.
What Causes a 401 Error
The trigger is always the same at the protocol level: the server could not validate your credentials. The reasons it could not vary quite a bit.
Diagnose Your 401 Error in Five Questions
Most guides hand you a list of causes and leave you to guess which one applies. Work through these five questions instead. Each answer eliminates entire categories of cause and points you at the right fix.
Question 1: Does it still fail in an incognito window?
It works fine there. The problem is local to your browser profile. Cached credentials, stale cookies, or an extension altering headers are the likely causes. Clear site data for that specific domain and retest.
It still fails. Your browser profile is not the issue. Move to question 2.
Question 2: Are you loading a page or making a programmatic request?
A page in a browser. Go to question 3.
An API call, script, or integration. Go to question 4.
Question 3: Does a native browser popup ask for a username and password?
This one detail separates two completely different problems, and it takes one second to check.
Yes, a small system dialog appears. You are hitting server-level HTTP Basic authentication through .htpasswd on Apache or auth_basic on nginx. Leftover staging protection is the most common reason. Skip to the WordPress section below.
No, you see a styled error page. Authentication is happening inside the application. An expired session or a rejected login is the likely cause, and logging in again usually resolves it.
Question 4: Does the response include a WWW-Authenticate header?
Check the raw response headers in your browser’s network tab or your API client. This header is where the server tells you exactly what it wants.
Yes, and it names an error. Read the error value. A value of invalid_token points to an expired or malformed credential. A value of insufficient_scope is a permissions problem wearing a 401 costume, and the endpoint should arguably return a 403.
No header at all. The server is not following the spec, which removes your best clue. Move to question 5 and verify the request end of the exchange instead.
Question 5: Is the Authorization header reaching the application?
This is the question that solves the 401s that feel impossible. Run the request with verbose output and read what actually left your machine.
curl -v -H “Authorization: Bearer YOUR_TOKEN” \
https://your-site.com/wp-json/wp/v2/users/me
The header is missing from the output. Your client is not sending it. Check how your HTTP library builds the request.
The header is sent but the server behaves as though it never arrived. Something between the two is stripping it. Apache, nginx, and reverse proxies all do this by default in certain configurations, and the server fixes below solve it.
The header arrives intact and is still rejected. The credential itself is the problem. Confirm it has not expired, regenerate it, and verify you are pointing at the right environment.
How to Fix a 401 Error as a Visitor
Start here if you hit the error while browsing someone else’s site. These steps run from most to least likely, and the first three resolve the large majority of cases.
How to Fix a 401 Error on WordPress
WordPress produces its own distinct flavors of this error, and the generic advice above rarely touches them.
Start at Tools, then Site Health, which flags a missing authorization header directly and can save you the whole investigation. Then work through these in order.
1. Look for leftover password protection
Server-level protection through .htpasswd triggers a 401 by design. Staging sites are frequently locked this way and then pushed live with the protection still attached.
Check your hosting control panel for a directory privacy or password protection setting on the site root or the wp-admin folder. Also open your .htaccess file and look for an AuthType Basic block.
AuthType Basic
AuthName “Restricted Area”
AuthUserFile /path/to/.htpasswd
Require valid-user
The fix: Remove the block if the protection is no longer wanted, or confirm you are entering the correct .htpasswd credentials rather than your WordPress login.
2. Fix the stripped Authorization header
This is the number one cause of REST API 401s on WordPress, and it is almost invisible without knowing to look for it. Apache commonly strips the Authorization header before it reaches PHP, particularly when PHP runs in CGI or FastCGI mode. WordPress never receives the Application Password you sent, and it rejects the request as unauthenticated.
The symptom is distinctive. GET requests often succeed while POST, PUT, and DELETE requests fail with a 401, using the exact same credentials.
The fix: Add this rewrite rule to your .htaccess file, above the standard WordPress block, to pass the header through.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* – [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Then confirm the header is arriving by testing the endpoint directly from the command line.
curl -u “username:application password” \
https://your-site.com/wp-json/wp/v2/users/me
If your site runs on nginx
The .htaccess file does nothing on nginx, which is why the fix above fails for a large share of WordPress sites. The equivalent lives in your PHP location block and passes the header through to PHP-FPM.
location ~ \.php$ {
include fastcgi_params;
fastcgi_param HTTP_AUTHORIZATION $http_authorization;
fastcgi_pass unix:/run/php/php-fpm.sock;
}
Reload nginx after saving, then rerun the curl test above. If you sit behind a reverse proxy as well, add proxy_set_header Authorization $http_authorization to the proxy block.
If PHP runs as CGI or FastCGI
Some hosts run PHP in a mode where the web server handles HTTP authentication itself and never passes the raw header along. The official WordPress Application Passwords documentation recommends stashing the value in REMOTE_USER instead.
RewriteRule .* – [E=REMOTE_USER:%{HTTP:Authorization}]
A handful of Apache stacks ignore the rewrite approach entirely. On those, setting the environment variable directly is the fallback that works.
SetEnvIf Authorization “(.*)” HTTP_AUTHORIZATION=$1
3. Check your security plugin
Security plugins routinely restrict REST API access, and many site owners never realize the setting exists. The useful part is that they usually announce themselves in the response body if you bother to read it.
Solid Security, formerly iThemes Security, returns a 401 carrying the error code itsec_rest_api_access_restricted when its API access setting sits on Restricted instead of Default. Wordfence offers a Disable REST API for non-admins option inside its All Options screen. Server-level WAF and mod_security rules can also intercept the request before WordPress sees it at all.
Test the endpoint by visiting yoursite.com/wp-json/ in a browser while logged in. A 200 response means the API is reachable, and a 401 or 403 confirms something is blocking it. Read the JSON body of the failure, because a named error code points straight at the plugin responsible.
The fix: Switch the plugin’s API access back to Default, or allowlist the specific routes you need, rather than disabling the plugin outright. If you cannot reach the admin, rename the plugin folder over FTP to deactivate it temporarily.
4. Regenerate your permalinks and .htaccess
There is a specific reason this works, and knowing it tells you when to reach for it. WordPress 5.6 added the Authorization header rewrite rule to the block it writes into .htaccess automatically. A site carrying an older or corrupted block is missing that line entirely.
Regenerating the file restores the current rules, header fix included, without editing anything by hand.
The fix: Go to Settings, then Permalinks, and click Save Changes without altering a thing. WordPress rewrites a clean block, and this step alone resolves a large share of REST API 401s.
5. Check the Application Password requirements first
Two requirements trip people up long before the credential itself is the problem. Application Passwords arrived in WordPress 5.6, and according to the WordPress developer documentation, they are available by default only when requests are served over HTTPS.
That HTTPS rule wastes more hours than any other item on this list. If WordPress does not detect the site as HTTPS, the Application Passwords section may not even appear on the user profile, and requests fail before your credential is ever examined.
The fix: Confirm the site runs on HTTPS and that WordPress detects it correctly. Then verify your WordPress version is 5.6 or newer, and check you are pairing the Application Password with the right username.
WordPress displays the generated password in spaced groups for readability, and it accepts the value with or without those spaces. The password appears only once at the moment you create it, which means copying it before you close the screen.
6. Isolate a plugin or theme conflict
A plugin filtering rest_authentication_errors can reject every unauthenticated request site-wide. Deactivate all plugins, confirm the error clears, then reactivate them one at a time until it returns. Turning on WordPress debug mode first will capture REST API errors that never appear on screen.
Diagnosing a 401 Error on IIS
Microsoft IIS does something no other server does, and almost nobody takes advantage of it. Instead of one generic 401, IIS records a substatus code that names the category of failure outright.
The codes are documented by Microsoft. They appear in the browser and in your server logs, and each one points at a completely different fix.
| Code | What IIS reports | Where to look first |
|---|---|---|
| 401.1 | Logon failed | The credentials themselves. Wrong username, password, or a locked account |
| 401.2 | Logon failed due to server configuration | The authentication method enabled in IIS does not match what the client sent |
| 401.3 | Unauthorized due to ACL on resource | NTFS file and folder permissions for the IIS account |
| 401.4 | Authorization failed by filter | A custom ISAPI filter installed on the server |
| 401.5 | Authorization failed by ISAPI/CGI application | The application handling the request, rather than IIS itself |
| 401.7 | Access denied by URL authorization policy | URL authorization rules on the web server. This code is specific to IIS 6.0 |
To find yours, open the most recent log file under C:\inetpub\logs\LogFiles\W3SVC1\ and look for the sc-substatus field on the failed request. The number after the 401 is the one that matters.
The payoff is precision. A 401.3 sends you straight to NTFS file permissions on the resource, while a 401.2 means the authentication method configured on the server does not match what the client offered. Guessing between those two can burn an afternoon.
How to Fix a 401 Error on API Requests
Developers hit 401s constantly, usually while integrating something that worked fine yesterday. Work the list in this order and you will find it faster.
How to Return a 401 Correctly (for API Builders)
Everything above assumes you received the error. If you are the one building the API, the rules run in the other direction, and getting them right saves every developer who integrates with you a great deal of guessing.
Always send a WWW-Authenticate header.
This is not optional. RFC 9110 requires that a server generating a 401 MUST include at least one challenge. Omitting it leaves clients unable to tell a missing token from an expired one.
Return 401 for identity failures and 403 for permission failures.
A missing Authorization header is always a 401. Returning a 403 there tells the client it is authenticated when it is not, and sends them debugging the wrong thing entirely.
Name the failure in the challenge.
The error and error_description parameters cost you nothing and save your users an hour. A response that says the access token expired is worth ten support tickets.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm=”api.example.com”,
error=”invalid_token”,
error_description=”The access token expired”
Never leak information in the error.
Telling an attacker that a username exists but the password was wrong hands them half the credential. Keep the distinction generic in the response body while staying specific about the token state.
Document your scheme clearly.
State whether you expect Basic, Bearer, or something custom, and give a working example. A large share of integration 401s trace back to a developer guessing the scheme from an incomplete doc.
What Site Owners Should Do About 401 Errors
A 401 on your own site is a conversion problem before it is a technical one. Every visitor who cannot log in either leaves or opens a support ticket, and most choose the first option quietly.
Monitor your server logs for spikes in 401 responses. A sudden cluster usually points at a change you made, such as a plugin update, a new firewall rule, or an SSL migration. Treat it the same way you would treat a spike in 502 Bad Gateway or HTTP Error 503 responses.
Then fix the experience, not just the code. Replace the default browser error with a custom page that explains what happened and links to password recovery. Clear messaging at this moment saves the visitor a support ticket and saves you a frustrated customer.
Keep a record of what triggered each spike. Authentication problems tend to repeat, and a short internal note about the fix turns a two-hour investigation into a five-minute one the next time it happens.
Wrapping Up
That number on the screen turns out to be one of the more honest error codes on the web. It is not hiding a broken page or a vanished resource. It is asking a single question, and the question is who are you.
Answer it correctly and the door opens. Start with the WWW-Authenticate header if you are debugging an API, or with the Authorization header rewrite rule if you are on WordPress, since those two spots hold the answer far more often than a forgotten password does. Related codes worth bookmarking while you are here: HTTP error 521 for Cloudflare connection failures.
Start off with a powerful ticketing system that delivers smooth collaboration right out of the box.
Frequently Asked Questions
A 401 error means the server rejected your request because it lacks valid authentication credentials for the resource. The server understood the request and refuses to act until you prove who you are.
A 401 means the server cannot verify your identity, and valid credentials will fix it. A 403 means the server knows exactly who you are and denies access anyway, which is a permissions problem that credentials cannot solve.
Check the URL for typos, log in again to refresh an expired session, then clear your cached credentials and cookies for that site. If the error persists across browsers, the problem sits on the server rather than with you.
The most common cause is Apache stripping the Authorization header before WordPress receives it, which makes valid Application Passwords appear invalid. Security plugins blocking /wp-json/ routes are the second most common cause.
Either is possible. If the error appears in one browser and not another, the cause is local and cached data is the likely culprit. If it appears everywhere and other people report it too, the server configuration is at fault.
Pages behind authentication are never meant to be indexed, which makes a 401 on those completely harmless. A 401 returned on public pages by mistake will block crawlers from reaching your content, and that does cause ranking damage.
It is the header a server must include with every 401 response, naming the authentication scheme it expects, such as Basic or Bearer. It often carries an error description that identifies the exact reason the credentials failed.








Leave a Reply