Introduction

The WordPress REST API may return 404 errors when custom permalink structures conflict with the API's route parsing. This commonly occurs after changing permalink settings or on fresh installations where rewrite rules have not been flushed. The error manifests as:

```bash curl https://example.com/wp-json/wp/v2/posts # Returns: {"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}

# Or returns a 404 HTML page instead of JSON ```

Symptoms

  • /wp-json/wp/v2/posts returns 404 HTML page or rest_no_route JSON error
  • REST API worked before changing permalink settings
  • Custom post type endpoints return 404 while standard post endpoints work
  • API works with plain permalink structure (?p=123) but fails with custom structure
  • WordPress admin dashboard works normally; only REST API is affected

Common Causes

  • Permalink structure change did not flush rewrite rules
  • .htaccess file not updated with new rewrite rules after permalink change
  • Server configuration (Nginx) does not route /wp-json/ requests to index.php
  • Custom post type registered with show_in_rest => true but without proper rewrite rules
  • Caching plugin intercepting REST API requests

Step-by-Step Fix

  1. 1.Flush rewrite rules after any permalink change:
  2. 2.```bash
  3. 3.# Using WP-CLI
  4. 4.wp rewrite flush

# Or visit: Settings > Permalinks > Save Changes (no need to change anything) ```

  1. 1.Verify the REST API base URL is accessible:
  2. 2.```bash
  3. 3.curl -s https://example.com/wp-json/ | python3 -m json.tool | head -20
  4. 4.`
  5. 5.This should return a JSON object listing available API namespaces.
  6. 6.Configure Nginx to route REST API requests properly:
  7. 7.```nginx
  8. 8.location / {
  9. 9.try_files $uri $uri/ /index.php?$args;
  10. 10.}

location ~ \.php$ { fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } `` The try_files directive ensures /wp-json/wp/v2/posts is rewritten to index.php`.

  1. 1.Check for caching plugin interference. Exclude REST API paths from caching:
  2. 2.```php
  3. 3.// Add to wp-config.php or a mu-plugin
  4. 4.if (strpos($_SERVER['REQUEST_URI'], '/wp-json/') !== false) {
  5. 5.define('DONOTCACHEPAGE', true);
  6. 6.}
  7. 7.`
  8. 8.Verify REST API is enabled in WordPress:
  9. 9.```php
  10. 10.// Check if REST API is disabled by a plugin or security hardening
  11. 11.// This filter should NOT be present in your code
  12. 12.// add_filter('rest_authentication_errors', '__return_false');
  13. 13.`
  14. 14.Test with authentication if endpoints require it:
  15. 15.```bash
  16. 16.curl -s --user "admin:app_password" https://example.com/wp-json/wp/v2/posts
  17. 17.`

Prevention

  • Always flush rewrite rules after changing permalink structures, both in development and production
  • Include wp rewrite flush in your WordPress deployment scripts after database migrations
  • Exclude /wp-json/* paths from all caching layers (plugin, CDN, page cache)
  • Test REST API endpoints as part of your post-deployment verification checklist
  • Monitor REST API response times and error rates in your server access logs
  • Use the Health Check & Troubleshooting plugin to diagnose REST API issues without affecting live users
  • Keep index.php and .htaccess files under version control to track rewrite rule changes