Bug Resolved: .htaccess Trailing Slash Redirects caused WordPress 6.9 “bug”

I was able to resolve the WordPress 6.9 Gutenberg issue and actually it was neither a WordPress bug nor a Gutenberg issue. The root cause was a configuration issue in my .htaccess file.

The Actual Problem

A .htaccess rule enforced trailing slashes and caused 301 redirects if not existent. This was interfering with WordPress REST API endpoints. When the Gutenberg editor attempted to save content via /wp-json/wp/v2/posts/{id} endpoint, the redirect dropped the POST/PUT payload.

The critical insight: I did disable the related WordPress redirect plugin during my initial research, however the .htaccess rule modifications remained unchanged. Deactivating the related WordPress plugin did not ensure the adapted configuration files to be reverted.

Technical Details

The problematic rule:

# BEGIN Force Trailing Slash
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ https://{my TLD}/$1/ [L,R=301]
</IfModule>
# END Force Trailing Slash

What was happening:

  1. Gutenberg sends POST request to /wp-json/wp/v2/posts/xxxx?_locale=user
  2. Apache redirects with 301 to /wp-json/wp/v2/posts/xxxx/?_locale=user (trailing slash added)
  3. The HTTP 301 redirects on POST/PUT requests cause browsers to drop the request body
  4. Server receives empty request → saves empty post

The Solution

Exclude REST API and admin endpoints from trailing slash redirects:

# BEGIN Force Trailing Slash
<IfModule mod_rewrite.c>
RewriteEngine On
# Exclude wp-json (REST API) and wp-admin from trailing slash redirects
RewriteCond %{REQUEST_URI} !^/wp-json/
RewriteCond %{REQUEST_URI} !^/wp-admin/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ https://{my TLD}/$1/ [L,R=301]
</IfModule>
# END Force Trailing Slash

Verification

After applying the fix:

  • REST API requests return http status code 200 OK instead of 301 Moved Permanently
  • Chrome DevTools Network tab shows no redirects on /wp-json/ endpoints
  • Content saves correctly in Gutenberg editor
  • Request payload reaches the server intact

Key Takeaways

For WordPress admins:

  • .htaccess rules adadpted by deactivated plugins may persist
  • Always ensure to also check .htaccess when troubleshooting issues around WordPress REST
  • be careful when REST API endpoints are redirected with 301/302
  • Test configuration changes with browser DevTools Network tab

For debugging:

  • Use Chrome DevTools to inspect HTTP requests
  • Check both the request payload and response http status codes
  • Look at the Initiator tab to understand request origins
  • Don’t assume disabled plugins have fully reverted their configuration file changes

Additional Resources

Thanks to the WordPress Gutenberg team for the debugging help and guidance.

Be the first to comment

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.