Your WordPress application passwords keep failing to authenticate and you are staring at a 401 response with no clear reason why. The application password is correct, the user account exists, the REST API is enabled, but every request comes back “rest_cannot_create” or a 401 Unauthorized. This guide walks through every common cause in diagnostic order, from server-level header stripping down to role permission issues, with exact commands and code fixes for each.
If you are integrating an external tool with the WordPress REST API, these failures are the single most common blocker. We have seen every one of these causes while building ClearPost, which authenticates to WordPress sites via application passwords. The diagnostic order below mirrors how we troubleshoot, starting with the cause that accounts for the majority of silent failures.
Quick Diagnostic: Find Your Cause in 60 Seconds
Run this table top to bottom. Each row gives you a symptom to look for and where to jump in this guide for the full fix.
| Symptom | Likely Cause | Jump To |
|---|---|---|
| GET requests work, POST/PUT return 401 | Server strips Authorization header | Cause 1 |
| Site runs on http:// (not https://) | Application passwords disabled on non-SSL | Cause 2 |
| Worked before installing Wordfence or Solid Security | Security plugin blocking REST auth | Cause 3 |
| No “Application Passwords” section in user profile | Feature disabled by host, plugin, or filter | Cause 4 |
| Password string has spaces and looks truncated | <Spaces in password not handled correctly | Cause 5 |
| Auth succeeds but create/update returns 403 | User role lacks capabilities | Cause 5 |
| Everything configured but still fails | Hosting provider disabled the feature | Cause 7 |
Cause 1: Your Server Strips the Authorization Header

This is the most common cause. Apache running PHP via mod_cgi or PHP-FPM strips the Authorization header before it reaches PHP by default. The request arrives at WordPress with no credentials, WordPress treats it as anonymous, and you get a 401 or “rest_cannot_create” error even though your client is sending a valid Authorization header.
Symptom
GET requests succeed because public reads require no authentication. POST, PUT, and DELETE requests fail with 401 because writes require authentication, and the credentials never arrive at PHP. If you inspect the request headers inside WordPress, $_SERVER['HTTP_AUTHORIZATION'] will be empty or absent.
How to Confirm It
Add this snippet to your theme’s functions.php or a must-use plugin to log whether the Authorization header is arriving:
add_action( 'rest_api_init', function() { error_log( 'AUTH HEADER: ' . var_export( $_SERVER['HTTP_AUTHORIZATION'] ?? 'MISSING', true ) ); }, 1 );
Check wp-content/debug.log after sending an authenticated request. If it logs “MISSING”, the header is being stripped. If it logs the base64 string, the header is arriving and the problem is elsewhere.
The Fix for Apache (.htaccess)
Add the following lines to your .htaccess file, above the standard WordPress rewrite rules. The order matters because the [L] flag on later rules would prevent this one from executing if placed after them:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Both approaches accomplish the same thing: they tell Apache to pass the Authorization header through to PHP. The SetEnvIf method works on older Apache versions as well. After applying the fix, clear any opcode cache and retest.
Alternatively, if you are on Apache 2.4.13 or later, you can use the cleaner directive in your server config or virtual host block (not .htaccess):
CGIPassAuth On
The Fix for Nginx (nginx.conf)
Nginx does not automatically pass the Authorization header to PHP-FPM. You need to add a fastcgi_param line inside your PHP location block. Find the block that handles .php requests (it usually contains fastcgi_pass) and add this line alongside the other fastcgi_param entries:
location ~ .php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_AUTHORIZATION $http_authorization;
}
If your nginx setup uses a reverse proxy to another server, use proxy_set_header instead:
proxy_set_header Authorization $http_authorization;
proxy_set_header Host $host;
After making either change, test your nginx config with nginx -t and reload with systemctl reload nginx.
Cause 2: Application Passwords Require HTTPS

WordPress silently disables application passwords on sites served over plain HTTP. This is an intentional security measure: Basic Auth credentials sent over unencrypted HTTP are visible to anyone on the same network. WordPress checks whether the request is over HTTPS before making the feature available, and if it is not, the feature is simply off. No error message, no log entry, no warning in the admin UI. The application password you generated may not even appear in your profile.
Symptom
Authentication fails on a site that loads over http://. The application passwords section may be missing from the user profile page, or it may be present but requests still return 401. If you recently migrated from HTTP to HTTPS or vice versa, this can surface unexpectedly.
How to Confirm It
Check the site URL in Settings > General. If either the WordPress Address or Site Address uses http://, application passwords are disabled by default. You can also query the REST API root endpoint and inspect the authentication key in the response:
curl https://example.com/wp-json/
In the JSON response, look for "authentication": {"application-passwords": {...}. If the authentication key is empty or missing, application passwords are not available on that site.
The Fix
The correct fix is to install an SSL certificate and serve the site over HTTPS. Let’s Encrypt provides free certificates, and most hosts offer one-click SSL setup. Once the site loads over https://, application passwords become available automatically.
If you are in a local development environment and need application passwords over HTTP temporarily, you can force the feature on with a filter. Add this to a must-use plugin or your theme’s functions.php:
add_filter( 'wp_is_application_passwords_available', '__return_true' );
Never deploy this filter to a production site. Application passwords over HTTP send credentials in base64-encoded plaintext, which is visible to anyone on the same network. For a deeper look at how the REST API handles authentication failures, see our guide on fixing the rest_cannot_create error, which covers related authentication and permission issues.
Cause 3: A Security Plugin Is Blocking REST Authentication

Security plugins can intercept REST API requests and block them before WordPress processes authentication. The request never reaches the application password verification logic, so valid credentials are rejected. This is one of the most frustrating causes because everything on your end is correct and the failure is silent.
Wordfence
Wordfence can block REST API authentication through two mechanisms. First, if your application password’s source IP gets flagged by the Web Application Firewall or rate limiting, requests from that IP start returning 403. Second, Wordfence’s “Block Access to REST API” setting (under Firewall > Advanced) can restrict REST API access entirely or limit it to specific namespaces.
To confirm, temporarily disable Wordfence and retry your request. If authentication succeeds with Wordfence off, it is the cause. To fix it, whitelist the IP address making your API calls in Wordfence > Firewall > Blocking > Allowlisted IPs. Also verify that REST API access is not restricted under Firewall > All Options > Rate Limiting.
Solid Security (formerly iThemes Security)
Solid Security can disable the REST API or restrict it to authenticated users only. Under Security > Settings > WordPress Tweaks, there is a “REST API” section with options to restrict API access. If “Restrict REST API access” is enabled, unauthenticated requests are blocked, and depending on the configuration, even authenticated requests may be filtered.
To confirm, check the WordPress Tweaks section and look for any REST API restrictions. Temporarily disabling the plugin and retesting is the fastest confirmation. To fix it, ensure REST API access is set to “Open” or that your application password requests are not being caught by a broader restriction.
All In One WP Security
All In One WP Security includes a feature that blocks users from making REST API requests unless they are logged in. Under WP Security > Application Firewall > REST API, the plugin offers options to restrict API access to logged-in users. The problem: “logged in” refers to cookie-based authentication, not Basic Auth via application passwords. Your application password request is treated as a non-logged-in user and gets blocked.
To confirm, disable the REST API restriction in the plugin settings and retest. If the request succeeds, that restriction was the blocker. Adjust the setting to allow authenticated REST API access, or whitelist your application password endpoint.
For a broader look at how plugins affect your WordPress setup, our comparison of automated SEO tools for WordPress covers how different plugins interact with the REST API and content publishing workflows.
Cause 4: The Application Passwords Section Is Missing
If you go to Users > Profile and there is no “Application Passwords” section at all, the feature has been disabled at the code level. This can happen through a must-use plugin, a theme’s functions.php, a security plugin, or a hosting provider’s configuration.
Symptom
The “Application Passwords” section is absent from the user profile page. You scroll to the bottom of Users > Profile and it simply is not there.
How to Confirm It
Check whether the feature is available by calling wp_is_application_passwords_available(). Add this to a temporary must-use plugin:
Application Passwords available: ' . ( $available ? 'Yes' : 'No' ) . 'add_action( 'admin_notices', function() {
$available = wp_is_application_passwords_available();
echo '
} );
If it returns “No”, something is disabling the feature. Search your mu-plugins directory, your theme’s functions.php, and any security plugins for the filter wp_is_application_passwords_available set to __return_false.
The Fix
Remove or comment out the filter that disables the feature. If you do not know which plugin or theme file is responsible, search the entire codebase:
grep -r "wp_is_application_passwords_available" wp-content/
If the feature is disabled for specific users rather than globally, look for the wp_is_application_passwords_available_for_user filter instead. This filter allows granular control, for example restricting application passwords to administrators only. The code looks like this:
add_filter( 'wp_is_application_passwords_available_for_user', function( $available, $user ) {
if ( ! user_can( $user, 'manage_options' ) ) {
$available = false;
}
return $available;
}, 10, 2 );
If your user role does not match the filter’s condition, the section will not appear for you. Either adjust the filter or use an account that meets the condition.
Cause 5: Role and Capability Problems
Authentication can succeed (the application password is valid, the header arrives, HTTPS is in place) but the request still returns 403 Forbidden. This means the user account authenticated correctly but lacks the capabilities needed for the specific REST API endpoint being called.
Symptom
You get a 403 response, not a 401. The response body typically includes "code": "rest_cannot_create" or "rest_cannot_edit". This tells you the credentials were accepted but the user does not have permission for that action.
How to Confirm It
Check the user role assigned to the account that generated the application password. If it is a Contributor or Subscriber, they cannot create or edit posts. Author can create posts but cannot edit others’ posts. Editor can manage all posts. Administrator has full access.
| Role | Can Create Posts | Can Edit Others’ Posts | Can Publish |
|---|---|---|---|
| Subscriber | No | No | No |
| Contributor | Yes (draft only) | No | No |
| Author | Yes | No | Yes |
| Editor | Yes | Yes | Yes |
| Administrator | Yes | Yes | Yes |
Also check whether a custom role has been created with limited capabilities. Use a plugin like User Role Editor or check the role definition in wp_options under the user_roles key.
The Fix
Either change the user’s role to one with the capabilities you need (Editor or Administrator for full post management) or add specific capabilities to the current role. If you are building a dedicated API user, the minimum recommended role is Editor, which can create, edit, and publish all post types without granting full admin access.
To add capabilities programmatically:
$role = get_role( 'contributor' );
$role->add_cap( 'edit_posts' );
$role->add_cap( 'publish_posts' );
$role->add_cap( 'edit_others_posts' );
Be cautious with capability grants. The principle of least privilege applies: give the role only what it needs for the API operations you are performing.
Testing Your Fix With curl

Once you have applied your fix, test authentication with a single curl command. This isolates the WordPress authentication layer from any client library, plugin, or wrapper that might be introducing its own issues.
curl -i --user "USERNAME:APPLICATION_PASSWORD" https://example.com/wp-json/wp/v2/users/me
Replace USERNAME with your WordPress login and APPLICATION_PASSWORD with the application password you generated. The -i flag shows the full response headers, which helps you distinguish between 401 (authentication failed) and 403 (permission denied).
What a Successful Response Looks Like
A successful request returns HTTP 200 with a JSON body containing your user data:
HTTP/2 200
Content-Type: application/json
{
"id": 1,
"name": "admin",
"slug": "admin",
"capabilities": { ... }
}
Interpreting Failure Responses
| HTTP Status | What It Means | Next Step |
|---|---|---|
| 401 Unauthorized | Credentials not received or invalid | Check Cause 1 (header stripping) and Cause 2 (HTTPS) |
| 403 Forbidden | Credentials accepted but user lacks permissions | Check Cause 5 (role and capabilities) |
| 404 Not Found | REST API endpoint is blocked or permalinks need flushing | Check Cause 3 (security plugins), re-save permalinks |
Spaces in the Application Password
WordPress generates application passwords as 24-character strings with spaces every 4 characters (for example: abcd efgh ijkl mnop qrst uvwx). The spaces are there for readability and are stripped automatically by WordPress before validation. This means you can include or omit spaces when using the password and it will work either way.
If you are still seeing failures after confirming the password is correct, check whether your HTTP client or shell is interpreting spaces in the password as argument separators. In curl, wrap the entire credentials string in quotes:
curl --user "username:abcd efgh ijkl mnop qrst uvwx" https://example.com/wp-json/wp/v2/users/me
If you are passing the password programmatically, strip the spaces before sending: $password = str_replace( ' ', '', $password ) in PHP or password.replace(/s/g, '') in JavaScript.
Hosting Providers That Disable Application Passwords
Some hosting providers disable application passwords at the platform level or strip the Authorization header in their server stack configuration. This is beyond your control via .htaccess or nginx.conf because the host intercepts the request before it reaches your site’s configuration.
Symptom
You have tried every fix in this guide and authentication still fails. The Authorization header is missing even after adding the .htaccess or nginx.conf fixes. The application passwords section is missing despite HTTPS being enabled.
How to Confirm It
Contact your hosting provider’s support team and ask specifically: “Does your platform pass the Authorization header to PHP, and are application passwords enabled for WordPress REST API authentication?” If they confirm they strip the header or disable the feature, you have found the cause.
Historically, WP Engine was known for stripping the Authorization header by default, though they later deployed a fix after the issue was raised by the WordPress REST API team. Other managed WordPress hosts may have similar configurations. If your host strips the header and refuses to change it, you can work around it by using a custom header name, but this requires custom code on both the client and server side.
The Fix
If your host strips the Authorization header, the most reliable fix is to request that they enable CGIPassAuth or equivalent header forwarding for your account. Most hosts will do this on request. If they will not, you have two options:
First, switch to a host that supports standard Authorization headers. This is the cleanest solution. Second, use a plugin that replaces the Authorization header with a custom header (for example, X-Auth) and modify both your client and server to use that header instead. This is fragile and should be a last resort.
Putting It All Together: A Diagnostic Checklist
Run through these steps in order. Most failures are resolved by step 3.
- Run the curl test command from the Testing section. Check the HTTP status code.
- If 401: check whether the Authorization header is being stripped (Cause 1) or the site is on HTTP (Cause 2). >li>If 403: check the user role and capabilities (Cause 5).>li>If 404: check for security plugin interference (Cause 3) and flush permalinks.>li>If the Application Passwords section is missing from the profile: check for disabling filters (Cause 4) or hosting restrictions (Cause 7).>li>If everything works but a specific tool fails: check whether the tool is handling spaces in the password correctly (Cause 5).
If you are integrating an external content tool with WordPress and need a reliable authentication path, these are the exact steps we follow at ClearPost when connecting to a new WordPress site. Getting application passwords right is the foundation that makes automated publishing work.
Frequently Asked Questions
Why does my WordPress application password return a 401 error even though the password is correct?
The most common cause is that Apache or Nginx is stripping the Authorization header before it reaches PHP. Add SetEnvIf Authorization “(.*)” HTTP_AUTHORIZATION=$1 and RewriteRule .* – [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] to your .htaccess, or fastcgi_param HTTP_AUTHORIZATION $http_authorization to your nginx config. For Nginx, also add fastcgi_pass_header Authorization.
Do WordPress application passwords work over HTTP without HTTPS?
WordPress disables application passwords by default on sites served over plain HTTP. The feature is silently unavailable and the Application Passwords section may not appear in the user profile. Install an SSL certificate and serve the site over HTTPS. For local development only, you can force it on with add_filter( ‘wp_is_application_passwords_available’, ‘__return_true’ ).
Do I need to remove spaces from my WordPress application password?
No. WordPress generates passwords with spaces every 4 characters for readability but strips them automatically before validation. You can include or omit spaces when sending the password. Just wrap the credentials in quotes when using curl to prevent shell interpretation issues.
What is the difference between a 401 and 403 response when using application passwords?
A 401 means the credentials were not received or were invalid. Check for Authorization header stripping (Apache/Nginx) or missing HTTPS. A 403 means credentials were accepted but the user lacks permissions for that action. Check the user role and capabilities. An Editor role is the minimum recommended for full post management via the REST API.
Can my hosting provider block WordPress application passwords?
Some hosting providers strip the Authorization header at the platform level or disable application passwords in their WordPress configuration. Contact your host and ask if they pass the Authorization header to PHP and support application passwords. WP Engine was historically known for this issue but later deployed a fix. If your host will not enable header forwarding, switching hosts is the most reliable solution.
