# “Cloudflare Rejected the API Token” — Five Causes, Five Fixes

> 'Cloudflare rejected the API token' in ForgeCache has five causes: truncation, wrong token type, missing Cache Purge permission, expiry, or whitespace.

- Canonical: <https://royalplugins.com/support/forgecache/cloudflare-invalid-api-token/>
- Last updated: 2026-06-01
- HTML version: <https://royalplugins.com/support/forgecache/cloudflare-invalid-api-token/>

---

When ForgeCache’s **Test connection** button (or an auto-purge in the background) reports *“Cloudflare rejected the API token. Make sure the token has the ‘Zone → Cache Purge: Purge’ permission on this site’s zone”*, the Cloudflare API has returned a 401 or 403 to ForgeCache’s request. Five known causes account for nearly all of these failures. This doc maps the symptom to the cause to the fix.

Haven’t done initial setup yet?

This doc assumes you’ve already pasted token + Zone ID into ForgeCache and the Test connection button is failing on this specific message. If you’re new to the Cloudflare integration, start with the [**Connecting Cloudflare to ForgeCache**](https://royalplugins.com/support/forgecache/connecting-cloudflare/) setup walkthrough — that covers token creation and what the right permissions look like.

### The Five Causes (in order of how often we see them)

**1. Copy/paste truncation** — the most common cause by a wide margin. The token got cut off when copying from Cloudflare or pasting into ForgeCache.
**2. Wrong token type** — user pasted the legacy *Global API Key* instead of a scoped API token.
**3. Missing or wrong permission** — the token exists but doesn’t have Cache → Purge on the right zone.
**4. Token expired or revoked** — you set a TTL that lapsed, or the token was deleted in Cloudflare.
**5. Whitespace contamination** — an invisible space or newline got into the field on paste.

## Symptoms

You probably have this issue if all of the following match:

#### The Telltale Signs

- You’ve enabled CDN Integration in **ForgeCache → Settings → Advanced**, picked **Cloudflare** as the provider, and pasted both API Token + Zone ID values.
- Clicking **Test connection** turns the status text red and shows *“Cloudflare rejected the API token. Make sure the token has the ‘Zone → Cache Purge: Purge’ permission on this site’s zone.”*
- The same message appears in PHP error logs after auto-purge events (e.g. saving a post) if auto-purge is enabled.
- You did *not* get *“Cloudflare returned 404”* (that’s a different problem — Zone ID mismatch) or *“Cloudflare rate-limit hit”* (429).

What ForgeCache’s message actually maps to

ForgeCache wraps the underlying Cloudflare API response. When CF returns HTTP `401 Unauthorized` or `403 Forbidden`, ForgeCache normalizes both into the single message you see. The underlying Cloudflare error codes (like `10000` “Authentication error” or `10004` “Permission denied”) are visible in Cloudflare’s own dashboard audit log if you want to dig into them, but you don’t need them to fix this — the five causes below cover what we see in practice.

## Verify It’s a 401/403 (Not a 404 or 429)

One curl test from any terminal confirms which HTTP code Cloudflare is returning for your token. Run this from your own machine (not your WP server) — macOS, Linux, Windows PowerShell, and WSL all work. Substitute your actual token + Zone ID in place of the placeholders:

```
curl -s -o /dev/null -w "%{http_code}\n" \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  https://api.cloudflare.com/client/v4/zones/<your-zone-id>
```

The number printed is the HTTP status code Cloudflare returned:

| HTTP code | What it means | Where to go next |
| --- | --- | --- |
| `200` | Token + Zone ID both valid. Surprise — the issue is elsewhere. | Re-save the ForgeCache settings page (without changing the values) and retest. If still failing, see the [whitespace section](#cause-5) — the value saved into wp\_options may differ from what you just curled with. |
| `401` or `403` | Token is being rejected — this article applies. | Continue to the five causes below. |
| `404` | Token works but the Zone ID doesn’t match any zone this token can see. | You probably pasted the Account ID instead of the Zone ID. Re-check **Step 2** of the [setup walkthrough](https://royalplugins.com/support/forgecache/connecting-cloudflare/#find-zone-id). |
| `429` | Token works but you’ve hit the 1,000-purges-per-zone-per-24h rate limit. | Wait for the 24h window to roll over, or contact Cloudflare support to raise the limit on a paid plan. |

Why curl reproduces what ForgeCache sees

ForgeCache uses `wp_remote_request()` with the same `Authorization: Bearer <token>` header structure the curl above sends. If curl returns 200, the token works against Cloudflare from your machine — meaning the issue is in how the value is stored or sent from your WP host (whitespace, encoding, or, rarely, a host firewall blocking outbound HTTPS to api.cloudflare.com).

## Cause 1 — Copy/Paste Truncation

The most common cause. Cloudflare’s tokens are long enough that a stray click, double-click selection, or autoclose dialog can truncate the string in the clipboard. Symptom: the verify curl returns 401.

### How to confirm

Cloudflare API tokens are a single long alphanumeric string (no dashes, no underscores, no spaces). Open **ForgeCache → Settings → Advanced**, click in the **API Token** field, and use your browser’s Inspect tool to view the actual saved value (Right-click the field → Inspect → the `value` attribute shows the full string regardless of the password mask). If it looks notably shorter than what you originally copied from Cloudflare, you’ve got truncation.

### The fix

#### Re-open the API Tokens page in Cloudflare

Go to [dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens). Find the token you created for ForgeCache. Cloudflare won’t show you the original value again — you’ll need to **Roll** (regenerate) it.

#### Roll (regenerate) the token

Open the actions menu on the token row (the icon location varies in Cloudflare’s redesigned UI — look for a kebab, gear, or actions button) and choose the option labeled **Roll** or **Regenerate**. Cloudflare issues a fresh string. **Click Copy immediately** — this new value is the only chance to grab it cleanly.

#### Paste cleanly into ForgeCache

Back in WP Admin, **ForgeCache → Settings → Advanced → CDN Integration → API Token**. Clear the field completely (Ctrl/Cmd-A then Delete), then paste. Save Changes. Retest.

## Cause 2 — Pasted the Global API Key Instead of a Scoped Token

Cloudflare has two distinct credential systems. The **Global API Key** is the older, account-wide secret used for direct API access — it has access to everything on your account (DNS, billing, zone transfers, the lot). The **API Tokens** system is the newer, scoped credential pattern — one token, one permission, one zone.

ForgeCache supports **API Tokens only**. The Global API Key uses a different auth header format (`X-Auth-Email` + `X-Auth-Key` instead of `Authorization: Bearer`) and ForgeCache will not authenticate with it. If you pasted the Global API Key by mistake, every call returns 401.

### How to confirm

Open [dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens). On the same dashboard page there’s a separate **API Keys** area (its exact location may differ in the redesigned UI — it’s the section that exposes the **Global API Key** + Origin CA Key). If the value you pasted into ForgeCache is from *API Keys* rather than *API Tokens* — especially the Global API Key — that’s the wrong credential.

### The fix

Create a proper scoped API token. The [**Step 1 of the setup walkthrough**](https://royalplugins.com/support/forgecache/connecting-cloudflare/#create-token) covers this in detail. The short version:

#### API Tokens → Create Token

Same page, but in the **API Tokens** section at the top. Click **Create Token**.

#### Scope to Specific zone → your domain

In the Edit policy panel, switch the scope dropdown from **Entire Account** to **Specific zone**, pick your domain.

#### Permission: Cache → Purge

Expand **Cache & Performance** (or search for “cache”). Tick the **Cache** row, dropdown value **Purge**.

#### Review token → Create Token → Copy

Paste into ForgeCache, save, retest. The connection should now succeed.

Don’t leave the Global API Key sitting in your WordPress database

If you confirmed you pasted the Global API Key, clear the field in ForgeCache and Save Changes before doing anything else. That key has full access to your entire Cloudflare account, and although ForgeCache’s settings page is admin-only, the principle of least privilege says don’t leave a master credential where a single compromised admin login can grab it.

## Cause 3 — Missing or Wrong Permission

You created a scoped token, but the permission isn’t **Cache → Purge** on the right zone. Common variants:

- Scoped to **Entire Account** instead of **Specific zone**
- Permission is something else under **Cache & Performance** (like **Cache Settings — Read**)
- Permission is correct but scoped to the *wrong* zone (a different domain on your CF account)

### How to confirm

Cloudflare doesn’t let you see a token’s configuration after creation through the dashboard list view — but you can use the token itself to ask Cloudflare what it’s allowed to do. Substitute your token in place of the placeholder:

```
curl -s -H "Authorization: Bearer <your-token>" \
  https://api.cloudflare.com/client/v4/user/tokens/verify
```

The response includes a JSON block that lists the token’s policies. If you see no Cache Purge policy, or the scope is wrong, the permission is the cause.

### The fix

You can’t edit a token’s permissions after creation — you have to delete it and create a fresh one. Follow [**Step 1 of the setup walkthrough**](https://royalplugins.com/support/forgecache/connecting-cloudflare/#create-token), paying particular attention to:

- **Scope must be Specific zone**, not Entire Account — otherwise Cache Purge doesn’t appear.
- **Permission must be Cache → Purge**, not Cache Settings — Cache Settings is read-only and gives the wrong rights.
- **Zone selection must match the Zone ID you pasted into ForgeCache** — if you have multiple domains on your Cloudflare account, you need a token scoped to *this* domain’s zone.

## Cause 4 — Token Expired or Revoked

When you create a Cloudflare API token, you can set an expiration date or pick **No expiration**. If you picked an expiration that has now passed, the token returns 401 on every call from then on. Tokens can also be deleted (revoked) from the API Tokens page — you, another admin on your CF account, or a security cleanup script could have done this.

### How to confirm

Open [dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens). Find your ForgeCache token in the list. Each row shows status: **Active**, **Expired**, or the token may simply be absent (revoked). The status will tell you which.

### The fix

Both cases resolve the same way — you need a fresh token. Two paths:

#### If the token is shown as Expired:

Open the actions menu on the token row and choose **Roll** (sometimes labeled **Regenerate**). Cloudflare issues a new value with the same permissions, but you choose a new expiration. Set **No expiration** if you don’t want to deal with this again, or pick a duration you’ll actually remember to renew.

#### If the token is missing entirely (revoked):

Create a fresh token following [**Step 1 of the setup walkthrough**](https://royalplugins.com/support/forgecache/connecting-cloudflare/#create-token). Paste into ForgeCache, save, retest.

Avoid silent breakage from expiring tokens

If your security policy requires token rotation, pick a duration you’ll actually action before it expires. An expired token silently stops working — your auto-purge stops firing without raising any alert in WordPress, so your edge cache gradually goes stale. Set a calendar reminder a week before expiration, or use **No expiration** and rotate manually on a schedule you control.

## Cause 5 — Whitespace Contamination

An invisible space, tab, or newline got into the API Token field on paste. This is unusual but happens when copying from certain browser dialog boxes that put a trailing newline on the clipboard. ForgeCache trims whitespace from both ends of the value on save, but a stray character *inside* the token (which can happen if you re-edited the field after pasting) breaks authentication while looking visually correct.

### How to confirm

The simplest check: in the verify curl from earlier, the token *worked* (returned 200), but the ForgeCache test still fails. That mismatch means the saved value differs from what you just curled with.

### The fix

#### Clear the API Token field completely

Click in the field, Ctrl/Cmd-A to select all, Delete. The field should be empty before you paste again.

#### Re-copy the token from Cloudflare cleanly

If you have the token saved somewhere (password manager), copy from there. Otherwise, roll a fresh one from the Cloudflare API Tokens page and copy the new value directly from CF’s “Copy” button (not from a screenshot, not from a forwarded email).

#### Paste, save, retest immediately

Don’t click in the field or arrow-key around after pasting — that’s how stray characters get inserted. Paste → Save Changes → Test connection.

## Still Stuck? Email Priority Support

If you’ve worked through all five causes and the token is still being rejected:

Email **[support@royalplugins.com](mailto:support@royalplugins.com)** with the diagnostic info below. Priority email support is included with your ForgeCache Pro license — typical response time is within 24 hours.

#### Information to include in your email

- Your **ForgeCache version** (from WP Admin → Plugins). 2.1.18+ is required for the Cloudflare API integration.
- Your **WordPress version**, **PHP version**, and **hosting provider** (Tools → Site Health → Info).
- The **HTTP code** from the verify curl test above (200, 401, 403, 404, or 429 — this immediately tells us where to look).
- The **token’s status** on the Cloudflare API Tokens page (Active, Expired, missing).
- **Confirmation you used a scoped API Token**, not the legacy Global API Key.
- **Output of the verify curl test** with the token verify endpoint (`/user/tokens/verify`) — this shows the token’s actual policies.
- **Do NOT include the actual API token in your email.** If our team needs to reproduce, we’ll send a secure-form link.

Related ForgeCache docs

- [**Connecting Cloudflare to ForgeCache**](https://royalplugins.com/support/forgecache/connecting-cloudflare/) — the full setup walkthrough this fix doc refers back to.
- [**Connecting BunnyCDN to ForgeCache**](https://royalplugins.com/support/forgecache/connecting-bunnycdn/) — using BunnyCDN instead? Different API, similar shape.
- [ForgeCache Documentation](https://royalplugins.com/support/forgecache/) — back to the main support page.
