> ## Documentation Index
> Fetch the complete documentation index at: https://devs.surferseo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshoot the WordPress plugin

> Find the cause and the fix for connection, hosting, install, and transfer problems with the Surfer plugin.

Find the heading that matches your message. Each section explains the cause and fix. Messages appear in three places.

* **Log in and integrate with Surfer** opens Surfer's connect page in a new window. Errors appear above the organization picker.
* The plugin shows its own messages on its settings page, **Surfer** in wp-admin, and in the Surfer panel of the post editor.
* WordPress shows the plugin's notices at the top of wp-admin pages, for example about Wordfence or Elementor.

## Connecting

The connect page names the status your site or its host returned. Each fix is a change on your side.

### The pop-up does not open

**Log in and integrate with Surfer** opens Surfer in a new window. If your browser blocks it, the plugin shows `Please allow popup, to connect with Surfer`.

1. Allow pop-ups for your wp-admin address in the browser.
2. Select **Log in and integrate with Surfer** again.

### The connect page shows an error above the organization picker

After you select **Connect**, Surfer calls your site and reports the status your site or its host returned:

| Note | Meaning | Where to go |
| - | - | - |
| `Certificate issue` | The site's certificate is expired or for another name. | Renew the certificate or issue one for this domain. Connect again. |
| `Error code 301` | The site's address redirects. | [`Error code 301`](#error-code-301) |
| `Error code 401` | The site rejected Surfer's credentials. | [`Error code 401`](#error-code-401) |
| `Error code 403` | Something refused the request. | [`Error code 403`](#error-code-403) |
| `Error code 404` | Surfer could not find the plugin on the site. | [`Error code 404`](#error-code-404) |
| `Timeout` | The site took too long to answer. | Try again. If the timeout repeats, ask your host to raise the script execution limit to a finite value, such as 60 seconds. |
| `Unknown Error` | Surfer could not map the failure to a status. | [`Unknown Error`](#unknown-error) |
| `Invalid Token` | The connection token no longer matches. | [`Invalid Token`](#invalid-token) |

### `Invalid Token`

Your site answers `Token verification failed`, and Surfer shows:

`Oops, the connection token is invalid or has expired. Please try initiating the connection from WPSurfer settings again.`

The plugin keeps only the newest connection token:

* Selecting **Log in and integrate with Surfer** replaces the token.
* Completing the connection deletes the token.
* A window opened for an earlier token fails.

1. Close every open connect window.
2. In wp-admin, open **Surfer**.
3. Select **Log in and integrate with Surfer**.
4. Complete the connection in the new window.

### `Error code 301`

`The URL to your page is redirecting to another URL and REST API is not able to work with redirection.`

Surfer requests the address WordPress reports as its own and stops at the first redirect. A maintenance mode plugin redirects every request. So does a mismatch between that address and the one that serves the site, for example with or without `www`.

Surfer support's documented workaround for maintenance mode is to connect with it off. The redirect returns whenever the mode is on. A site that stays in maintenance mode needs the REST API exempted from it before later transfers, in the plugin that provides the mode or at your host.

1. If a maintenance mode plugin is on, turn it off.
2. Connect.
3. If the connection still fails, check that **Settings → General → WordPress Address (URL)** is the address that serves the site, including `https://` and `www` if you use them.
4. If the redirect comes from your host or CDN rather than WordPress, ask them to exempt the user agent `SurferSEO WP Plugin`. [`Error code 403`](#error-code-403) has the message to send.

### `Error code 401`

`Surfer was not able to authenticate. This could happen because you are using an old plugin version, some other plugin installed interferes with ours, or the server configuration is blocking REST API.`

The plugin identifies Surfer from each request's `Authorization` header.

These conditions produce the same status:

* Some servers drop the header before it reaches WordPress, particularly when PHP runs under CGI or FastCGI.
* Wordfence's application password setting blocks authentication.
* A broken permalink structure prevents authentication.

1. Check Wordfence's setting under [`Error code 403`](#error-code-403).
2. Go to **Settings → Permalinks**.
3. If **Custom Structure** is selected, keep only tags listed under **Available tags**.
4. Save the change.
5. Update the plugin from **Plugins**.
6. Open **Surfer**.
7. Select **Disconnect**, even if the screen says **Connected**.
8. Select **Log in and integrate with Surfer**.
9. Complete the connection in the new window.

If the status remains 401, the server is dropping the header. The server configuration changes below come from WordPress's [REST API FAQ](https://developer.wordpress.org/rest-api/frequently-asked-questions/). Ask your host to apply the relevant change if you cannot edit the configuration.

On Apache, add this block to the site's `.htaccess` to preserve the `Authorization` header for PHP.

```apache theme={"system"}
<IfModule mod_setenvif>
  SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
</IfModule>
```

On nginx, add this line to the server configuration's fastcgi section to pass the `Authorization` header.

```nginx theme={"system"}
fastcgi_pass_header Authorization;
```

### `Error code 403`

`Access to your page is forbidden. In most cases, the page is password protected, or REST API is restricted (by plugin or server configuration).`

Something in front of WordPress refused the request: Wordfence, another security plugin, a firewall at your host or CDN, or password protection. For password protection, see [The site is password protected or a staging site](#the-site-is-password-protected-or-a-staging-site).

When Wordfence's setting is the cause, the plugin says so in a wp-admin notice headed `WordFence is blocking Surfer!`. The notice continues with `WordFence option "Disable WordPress application passwords" is enabled. This option blocks Surfer API and you will be not able to use it.` and links to the option.

1. In wp-admin, go to **Wordfence → All Options → Brute Force Protection**.
2. Clear **Disable WordPress application passwords**.
3. Save the change.

A host, CDN, or security plugin can block the request before it reaches WordPress. Surfer's requests use the user agent `SurferSEO WP Plugin`. GoDaddy hosting and Cloudflare can block this user agent. Ask your provider to check what is blocking the request.

1. In a security plugin, allow the user agent `SurferSEO WP Plugin` in its REST API protection, or turn that protection off.
2. Otherwise, ask your host or CDN: "Please allow requests with the User-Agent `SurferSEO WP Plugin` to reach the WordPress REST API on my site. The Surfer plugin needs these requests."

Surfer cannot bypass a firewall or a bot challenge on your site. The exemption has to be made where the request is blocked.

### `Error code 404`

`URL to your REST API is not found. It can be hidden, or the rest route was not created.`

Surfer reaches the plugin through the WordPress REST API.

These conditions can produce this status:

* **Plain** permalinks leave the REST API unavailable at the address Surfer uses.
* Another plugin hides the REST API.
* The route cache is stale.
* The Surfer plugin is inactive.

1. Go to **Settings → Permalinks**.
2. Choose any structure other than **Plain**.
3. Save even if the structure is already correct. Saving rebuilds the routes.
4. Clear your caching plugin's cache.
5. On **Plugins**, check that Surfer is active and up to date.
6. If a security plugin hides or disables the REST API, allow it, at least for the user agent `SurferSEO WP Plugin`.
7. If the status stays 404, deactivate the other plugins.
8. Connect.
9. Reactivate one plugin.
10. Connect again.
11. Repeat these two steps for each remaining plugin.
12. If no plugin brings back the 404 status, switch to a default theme.
13. Connect again.

The plugin that brings back the 404 status removes the routes.

### `Unknown Error`

`Maintenance Mode is on or you are trying to connect using an old token (need to update the plugin to a new version).`

Surfer shows this note when it cannot map a failure to a status. For maintenance mode, follow [`Error code 301`](#error-code-301).

In the export dialog, the same note also appears when the document exceeds the plugin's 5 MB export limit. [Export from Surfer](/integrations/wordpress/export#confirm-and-finish) states the limit.

1. Shorten the document.
2. Export again.

For an old token:

1. Update the plugin from **Plugins**, or reinstall it if no update is listed.
2. Open **Surfer**.
3. Select **Disconnect**, even if the screen says **Connected**.
4. Select **Log in and integrate with Surfer**.
5. Complete the connection in the new window.

### The site is password protected or a staging site

Password protection at the server, the browser's own login prompt that staging sites use, stops Surfer's request before WordPress sees it. Surfer cannot answer that prompt. Surfer support documents two workarounds.

Prefer the exemption. It is a change on your server or at your host, and it leaves the protection in place. The address change is a WordPress setting that puts the login and password into your site's address. It is documented for connecting, and later transfers can hit the same prompt once you change the address back.

To exempt the REST API:

1. Exempt the WordPress REST API from the password protection in your server or hosting panel, or ask your host to.
2. Connect.

To connect through the address:

1. Go to **Settings → General**.
2. Set **WordPress Address (URL)** to `https://login:password@example.com`, with the protection's login and password and your own domain.
3. Save the change.
4. Connect.
5. Once the plugin's settings page shows **Connected**, change the address back.

## Installing

An install failure means WordPress could not download the archive completely or could not write it. Check free disk space and writable directories first.

### The install fails with `PCLZIP_ERR_BAD_FORMAT` or WordPress cannot copy a file

`PCLZIP_ERR_BAD_FORMAT` or a file-copy error means the archive arrived incomplete or WordPress could not write it. The causes are insufficient disk space or a directory WordPress cannot write to. The plugin is small, but it still needs space to unpack.

1. Open **Tools → Site Health → Info → Filesystem Permissions**.
2. Check that every listed directory is writable.
3. Open **Directories and Sizes** on the same screen to see how much space the installation uses.
4. Check free disk space with your host.
5. Free space or ask your host to make the directories writable.
6. Install again using [Set up](/integrations/wordpress/setup).

The plugin needs a few megabytes beyond its own size to download and unpack.

## Writing and transferring

The Surfer panel shows Surfer's response and status. The export dialog reports when Surfer cannot reach the plugin.

### `Quota exceeded` when creating a Content Editor

`422: Request failed with message: Quota exceeded - You do not have credits (Content Editor overage is not available via WordPress API)`

The **Optimize with Surfer** dialog shows this message after you select **Create CE for 1 credit** with no Content Editor credits left.

A [Content Editor](/integrations/guidelines-panel) is the document Surfer builds around your target keywords, with the guidelines and the Content Score. Creating one spends one credit. [Credits](/integrations/guidelines-panel#credits) covers the rule.

* Wait for the plan's credits to renew.
* Or create the Content Editor in Surfer and attach the post to it with **Overwrite existing Content Editor**, which spends none.

### `Too many keywords` when creating a Content Editor

`422: Request failed with message: Too many keywords`

The panel sent more keywords than a Content Editor takes. [Write in WordPress](/integrations/wordpress/write) gives the limit. Remove keywords, then create it again.

### `This Content Editor is already connected with another post`

`There was an error during export!` with `This Content Editor is already connected with another post. Disconnect it there first.`

The **Optimize with Surfer** or **Export to Surfer** dialog shows this after you select **Overwrite the CE**. The plugin refuses to send text because another post on this site is linked to the same Content Editor.

Exporting the Content Editor to a second post leaves the first post linked.

1. Open the other post linked to the Content Editor.
2. Unlink it with **Disconnect**, following [Unlink a post](/integrations/wordpress/write#unlink-a-post).
3. Return to your post.
4. Select **Overwrite the CE** again.

### The panel reports `Content Editor Failed` or `Your post needs attention`

The Surfer panel replaces the guidelines with one of two warnings, each with a **Disconnect** button.

| Warning | Meaning |
| - | - |
| `Content Editor Failed`, with `There was some error during Content Editor processing.` | Surfer marked the Content Editor's analysis as failed. |
| `Your post needs attention`, with `This post was connected to our previous plugin version. Please disconnect and reconnect it to make sure it continues to work properly.` | An older plugin version linked the post, and the link lacks the data the current version needs. |

1. Select **Disconnect**.
2. Start again from **Optimize with Surfer**. [Write in WordPress](/integrations/wordpress/write#optimize-a-post-with-surfer) covers both choices.

### The Keyword Research panel has no results for a keyword

Under **Keyword Ideas**, the panel reads `Sorry, we do not have results for this keyword. Please try different one`.

Surfer's keyword data holds no keyword ideas for that keyword. Try another keyword.

### The Surfer panel does not appear in Elementor

Elementor's editor shows no **Surfer** panel on its right edge, while the other editors show theirs.

The plugin setting **Disable Surfer writing guidelines in Elementor editor** is on. The plugin adds the panel to Elementor only while that setting is off. [Set up](/integrations/wordpress/setup#plugin-settings) lists the setting.

1. In wp-admin, open **Surfer**.
2. Clear **Disable Surfer writing guidelines in Elementor editor**.
3. Select **Save changes**.
4. Reload the Elementor editor.

### The Content Score does not update as you type

The score in the Surfer panel stays unchanged while you write.

The panel re-reads the post on a schedule that depends on the editor, so the score trails your typing. [Where your text lives](/integrations/guidelines-panel#where-your-text-lives) gives the delay for each editor. A post that is not attached to a Content Editor shows **Optimize with Surfer** in place of a score.

1. Stop typing and wait for the delay.
2. If the panel shows **Optimize with Surfer**, attach the post. [Write in WordPress](/integrations/wordpress/write#optimize-a-post-with-surfer) covers it.
3. If the score still does not follow, reload the editor. The panel reads the post again when it loads.

### A notice says there may be an issue with Elementor

The notice starts with `It appears there may be an issue with Elementor`.

It continues with this explanation:

`We have noticed that you are attempting to use the Elementor parser with the Surfer plugin while the Grid Container option is disabled. Please be aware that this configuration may lead to errors during the export process from Surfer.`

This wp-admin notice appears when Elementor is the selected content parser and its container feature is off. Exports can fail while that feature is off. Enable it before exporting.

1. Select **Please enable this option** in the notice. Elementor's settings open at the container feature.
2. Enable the container feature.
3. Save the change.

### The status line reads `Not connected to any WordPress site`

Below the **WordPress** button in the Content Editor, the status line lists the sites connected to your organization. The line reads `Not connected to any WordPress site` when your workspace's organization has no connected sites. A site connected to another organization also produces this state.

1. In Surfer, open **Settings → Integrations → WordPress**.
2. Check whether the site is listed.
3. If it is missing, connect it from the plugin using [Set up](/integrations/wordpress/setup).
4. Open the export dialog again.

The setup instructions explain which organization to choose.

### The export dialog shows `Connection issue` or `You don’t have access to advanced posting options`

The export dialog asks your site's plugin for posts and posting options. It reports two failures.

| Error | Meaning | Message |
| - | - | - |
| `Connection issue` | The plugin did not answer. | `We are unable to connect to this domain. Please check if WPSurfer is still installed on <your site> and is connected to your Surfer account. Using an old version of the plugin may also cause this issue.` |
| `You don’t have access to advanced posting options` | The plugin answered without the options provided by newer versions. | `You are using an old plugin version, you can upgrade it here. If you already have the latest version, please contact support.` |

Update from wp-admin rather than through the warning's link.

1. On **Plugins**, update Surfer if an update is listed.
2. Open **Surfer**.
3. Check that the settings page shows **Connected**.
4. If it does not, select **Log in and integrate with Surfer**.
5. Complete the connection in the new window.
6. In Surfer, open the export dialog again.

Removing the plugin leaves the site listed in Surfer. The export dialog can therefore offer a site that no longer responds. Follow [Set up](/integrations/wordpress/setup) to remove it.

### The export dialog cannot load custom fields

The **Custom fields** preview shows `Couldn't load custom fields` with `Something went wrong while loading custom field values. You can go back or try again in a moment.`, and the confirm button stays disabled.

Surfer could not load the site's Advanced Custom Fields values for the chosen type, and the dialog blocks the export until they load. [Export from Surfer](/integrations/wordpress/export#fill-in-the-post-settings) describes the preview.

1. Go back a step, then continue again.
2. If the preview fails again, wait a moment and retry.

### Images are missing after an export

The plugin saves exported images in the media library. By default, it downloads images in the background for exports with more than eight images. These images appear with a delay.

The plugin does not copy images outside its type, size, and count limits. [Images](/integrations/wordpress/export#images) covers image processing, its setting, and the limits.

1. Reload the post after a few minutes.
2. If an image shows the plugin's placeholder or still points to Surfer, check it against the limits.
3. If images are still missing, run the export again.

## Performance report

The report needs a Search Console connection made in Surfer and one completed weekly collection.

### The Search Console row stays `Not connected with Surfer`

The **Google Search Console integration** row on the plugin's settings page requires all three conditions:

* A Google account is connected in Surfer.
* That account can access a Search Console property for your site's domain.
* Your plan includes the WordPress integration.

Until these conditions are met, the row reads `Not connected with Surfer`. It checks again whenever the page loads.

1. Connect the Google account that can access the property using [Google Search Console](/integrations/google-search-console).
2. Check your plan against [Availability](/integrations/wordpress/setup#availability).
3. Reload the plugin's settings page.

The Google Search Console instructions also explain how the domain is matched.

### The report is empty

The report shows a date range above an empty table until the first weekly collection finishes. See [Performance report](/integrations/wordpress/performance) for the schedule. After the first collection, an empty week means Search Console had no data for the site's pages in that period.

1. After the first collection, open **Surfer → Performance Report**.
2. Compare the report with the property's data in Search Console. [Google Search Console](/integrations/google-search-console) explains when Google reports little or no data.

### The weekly email does not arrive

The plugin sends the email to the site's administration email address, at most once every seven days, and only after a weekly collection that returned data. The setting is off until you turn it on. It can be turned on only once the Search Console row reads **Connected**.

1. On the plugin's settings page, check that **Send me a weekly report on my site’s performance.** is on.
2. In wp-admin, check the administration email under **Settings → General**.
3. Wait for the next Monday collection. A week with no data sends no email.

## Send debug data to support

The plugin's settings page, **Surfer** in wp-admin, has a **Debugging** box with **Download debug data**, which saves the debug file. The file lists:

* The site and home addresses.
* The plugin, PHP, and WordPress versions.
* The permalink structure.
* The Search Console collection and email schedule.
* The organization the site is connected to.
* The file shows whether the site has a connection key. It includes only the key's last four characters.
* The active plugins.

## What Surfer supports

Surfer supports the plugin and its connection to your site. The vendors support your hosting, security plugins, caching plugins, page builders, and themes. Apply the relevant steps above in those tools. Ask the vendor for help when the steps do not fit your setup.

If a fix above does not solve it, write to [support@surferseo.com](mailto:support@surferseo.com) with:

* The site address.
* The exact message and where it appeared, whether the connect page, the Surfer panel, or a wp-admin notice.
* The debug file from **Download debug data**.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.