# Web Server 301-Redirects /register to /register/

> A 301 trailing-slash redirect on POST /register (Nginx or Apache mod_dir, .htaccess rules) blocks OAuth client registration with Royal MCP; fixes for each.

- Canonical: <https://royalplugins.com/support/royal-mcp/oauth-register-trailing-slash-301/>
- HTML version: <https://royalplugins.com/support/royal-mcp/oauth-register-trailing-slash-301/>

---

Royal MCP’s admin self-check flagged that your web server is responding to `POST /register` with a 301 redirect to `/register/` (with a trailing slash). OAuth clients don’t follow 301 on POST, so claude.ai’s registration request dies before it reaches WordPress — the connector silently fails with a generic “couldn’t reach the MCP server” error. This is a web-server canonicalization rule (Nginx, Apache, or .htaccess), not a Royal MCP setting. Here are the fixes for each common server.

### Detected by Royal MCP 1.4.22

This admin notice was added in Royal MCP 1.4.22. The plugin POSTs to `/register` every 12 hours and detects when the response is a 301 pointing at `/register/`. If you arrived here from the admin notice, the diagnosis is already done — jump to the fix for your web server below.

## Confirm What’s Happening

From any terminal:

```
curl -i -X POST -H "Content-Type: application/json" -d '{}' https://example.com/register
```

You’re hitting this issue if you see:

#### The Telltale Signature

- Status: **`HTTP/2 301`** (sometimes `301 Moved Permanently`)
- Header: **`Location: https://example.com/register/`** (trailing slash added)
- If you re-run with `-L` (follow redirects), curl will follow the 301 as a GET (per RFC 7231 it would, but real OAuth clients don’t) — this confirms the redirect target works fine and the issue is just that OAuth POSTs don’t follow 301

If the response is a 4xx, 5xx, or 200, you’re looking at a different issue and this guide doesn’t apply.

## Why This Happens

Nginx, Apache, and many `.htaccess`-based hosts emit a 301 redirect on any non-file URL path that lacks a trailing slash. The behavior is built into:

- **Nginx**: when a request path matches a directory location (or could match one), Nginx adds the slash via an internal redirect
- **Apache `mod_dir`**: the `DirectorySlash` directive (default `On`) does the same thing
- **Apache `mod_rewrite` / `.htaccess`**: many cPanel and shared-host default configs include a canonicalization rule that forces trailing slashes

For browser-facing pages this is fine — browsers follow 301 on GET. For OAuth, RFC 7231 specifically says clients SHOULD NOT auto-follow 301 redirects on POST (the response method-change behavior is undefined and unsafe). Real-world OAuth clients including claude.ai, mcp-remote, and Anthropic’s backend treat a 301 on a POST as a failure.

Royal MCP’s rewrite rules in 1.4.22+ match both bare and trailing-slash variants of `/register`, `/authorize`, and `/token` — so when WordPress handles the request internally, both forms work. But this web-server 301 happens *before* WordPress even sees the request, so the plugin can’t fix it from PHP. It has to be fixed in your web-server config.

## Fix: Nginx

Add a `location` block above your main `location /` block in your server config (usually `/etc/nginx/sites-available/your-site.conf` on Debian/Ubuntu, or `/etc/nginx/conf.d/your-site.conf`):

```
location = /register {
    try_files $uri $uri/ /index.php?$args;
}
location = /authorize {
    try_files $uri $uri/ /index.php?$args;
}
location = /token {
    try_files $uri $uri/ /index.php?$args;
}
```

The `=` prefix means “exact match” — Nginx evaluates these before any prefix or regex location, so the request goes straight to PHP without canonicalization. After saving, reload Nginx:

```
sudo nginx -t && sudo systemctl reload nginx
```

Re-run the curl test from the top — you should now see `HTTP/2 200` or a JSON error response instead of `HTTP/2 301`.

If you’re on Cloudflare in front of Nginx

Cloudflare can also produce a 301 trailing-slash redirect via the “Always Use HTTPS” or a Page Rule with the “Forwarding URL” action. Check Cloudflare Dashboard → Rules → Page Rules and Bulk Redirects for any pattern matching `/register`, `/authorize`, or `/token`. Disable or refine the rule to exclude these paths.

## Fix: Apache (with `mod_dir`)

In your virtual host config or in your site’s root `.htaccess`, add before the WordPress block:

```
<IfModule mod_dir.c>
    <LocationMatch "^/(register|authorize|token)$">
        DirectorySlash Off
    </LocationMatch>
</IfModule>
```

If you don’t have `<LocationMatch>` available (it requires server-config or virtual-host-level access), use the `.htaccess`-only version instead:

```
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^(register|authorize|token)$ index.php?$0 [L]
</IfModule>
```

Add this **above** the existing WordPress `# BEGIN WordPress` block in `.htaccess`. Reload Apache (`sudo systemctl reload apache2`) or just save the `.htaccess` file (Apache re-reads it per-request).

Re-run the curl test — you should no longer see a 301.

## Fix: LiteSpeed

LiteSpeed reads `.htaccess` files like Apache does, so the `mod_rewrite` snippet from the Apache section above works identically. After saving, you may need to clear the LiteSpeed cache:

```
WP Admin → LiteSpeed Cache → Toolbox → Purge All
```

Re-run the curl test to confirm.

## Verify the Fix Worked

1. Run the `curl` POST command from the top of this page again — you should now see a JSON response or a 4xx/5xx (Royal MCP responding), not a 301
2. In WordPress admin, go to **WP Admin → Royal MCP → Settings** and save the form to invalidate the 12-hour self-check transient
3. Reload any Royal MCP admin page — the “OAuth registration may be blocked” notice should no longer appear
4. Reconnect Claude.ai (or whichever MCP client was failing) — the OAuth handshake should now complete

## Still Stuck? Two Support Paths

If you’ve worked through the steps above and your connection still fails:

### Community Support (free) — wp.org Plugin Forum

Post a new thread at [wordpress.org/support/plugin/royal-mcp/](https://wordpress.org/support/plugin/royal-mcp/). The Royal Plugins team monitors the forum regularly and community members often help disambiguate issues faster than email could. Include the diagnostic info listed below in your post.

### Premium Support (paid) — direct one-on-one help

For priority response (24-hour SLA) and hands-on diagnostic help, our [Premium Support tier](https://royalplugins.com/premium-support/) is $149/year. Includes a 30-day “if it breaks again” follow-up window on every resolved ticket.

#### Information to include in your post or ticket

- Full `curl -i -X POST` output (headers + body)
- Your web server (Nginx / Apache / LiteSpeed) and the host (DigitalOcean, AWS, cPanel, Cloudways, etc.)
- Whether you’re behind Cloudflare, BunnyCDN, or another CDN/WAF
- Royal MCP version (must be 1.4.22 or newer for the self-check)
- What you tried from this article and what changed (or didn’t)

[/.well-known/ served as HTML](https://royalplugins.com/support/royal-mcp/well-known-served-as-html/)
[Back to Royal MCP Support](https://royalplugins.com/support/royal-mcp/)
