2026年11月14日
2026年11月14日
410 Gone in WordPress: How to Return It and Fix Unexpected 410 Errors
This article is a localized edition of the Japanese original. Read the Japanese original
"410 Gone" is an HTTP status code that means the page that used to be at this URL has been removed and will not come back (RFC 9110 15.5.11). Unlike 404, which only says "not found," it is used when the site owner deliberately wants to say "this no longer exists."
When you delete a post, WordPress does not return a 410. It returns a 404 for the URLs of deleted posts and pages. This article covers two situations:
- You want to return a 410 on purpose, for example for a finished campaign page
- A page shows a 410 even though you don't remember setting one up
404 vs. 410
| Item | 404 Not Found | 410 Gone |
|---|---|---|
| Meaning | Nothing is at this URL right now. Doesn't say whether it's temporary or permanent | The owner removed it on purpose and it won't return |
| WordPress default | Nonexistent URLs and deleted posts get this | Not returned by default (except for deactivated or archived sites in Multisite) |
| Typical use | Typos, pages not created yet | Finished campaigns, posts removed on purpose, URLs created by spam |
Google says it treats all 4xx status codes except 429 the same way, and removes previously indexed URLs from the index whether they return 404 or 410 (Google Search Central: HTTP status codes, network and DNS errors, as of November 2026). So if your only goal is to drop a page from search results, leaving it as a 404 is enough. Use 410 when you want to make clear that the removal was intentional, or to tell it apart from 404s (broken links) in logs and monitoring.
If a replacement page exists, send visitors there with a 301 redirect instead of a 410. The reasoning is explained in 301 redirects and SEO.
How to return a 410 in WordPress
Whichever method you use, check the status code afterward with this command.
curl -I https://example.com/old-campaign/
# Success if the first line is HTTP/1.1 410 Gone (HTTP/2 410 for HTTP/2)
If you use a caching plugin or a CDN, clear the cache after making the change before you check.
Method 1: Use the Redirection plugin
If you want to do everything from the admin screens, you can use the Redirection plugin. According to its documentation, when you choose "Error (404)" as the rule's action (When matched), you can pick the HTTP code to return from 400, 401, 403, 404, 410, 418, 451, 500, 501, and 502 (Redirection: Redirect Actions, as of November 2026).
- Open Tools → Redirection.
- Add a new redirect and enter the path of the removed page in "Source URL" (for example,
/old-campaign/). - Open the advanced options, set the action to "Error (404)", and choose
410as the HTTP code. - Save, then check with the
curl -Icommand above.
Field names may be translated in other admin languages. For the basics of the plugin, see How to use the Redirection plugin.
Method 2: Add it to Apache’s .htaccess
On Apache, Redirect gone from mod_alias returns a 410 (Apache mod_alias: Redirect). So that it is processed before WordPress's rewrite rules, put it above # BEGIN WordPress in .htaccess.
# Return 410 for finished pages (place above # BEGIN WordPress)
Redirect gone /old-campaign/
Redirect gone /2019-sale/
To cover several URLs with a pattern, use the G flag of mod_rewrite (Apache mod_rewrite: G flag).
<IfModule mod_rewrite.c>
RewriteEngine On
# Return 410 for everything under /campaign-2019/
RewriteRule ^campaign-2019/ - [G]
</IfModule>
If WordPress is installed in a subdirectory such as /blog/, include the subdirectory in the Redirect gone path. How to write .htaccess rules is covered in A guide to Apache .htaccess.
Method 3: Add it to the Nginx configuration
Nginx does not read .htaccess, so add the rules to the server block (ngx_http_rewrite_module: return).
location = /old-campaign/ {
return 410;
}
location ^~ /campaign-2019/ {
return 410;
}
sudo nginx -t && sudo systemctl reload nginx
Method 4: Return it from your theme’s functions.php or a custom plugin
If you can't change the server configuration, swap the status code in PHP. WordPress sets a 404 for nonexistent URLs before it runs template_redirect, so if you change the status to status_header( 410 ) there for specific URLs only, your theme's 404 template is displayed as-is with a 410 status.
<?php
// Return 410 for the URLs of removed pages (displayed with the theme's 404 template)
add_action( 'template_redirect', function () {
if ( ! is_404() ) {
return;
}
$path = wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
$path = untrailingslashit( (string) $path );
// If WordPress is installed in a subdirectory, include that path too
$gone = array(
'/old-campaign',
'/2019-sale',
);
if ( in_array( $path, $gone, true ) ) {
status_header( 410 );
}
} );
Because the code is limited by is_404(), if you later create a new page at the same URL, that page displays normally. Keep in mind that the code disappears when you switch themes; if you'll use it long term, put it in a small custom plugin.
When a 410 appears unexpectedly
If a 410 shows up although you don't remember setting one, check in order which layer is returning it. On Multisite, also check the site status described in the next section.
- Look at the response headers. Use
curl -Ito check headers such asserver,via, andcf-ray. If a CDN or WAF name appears, review that service's rules. - Redirection and other redirect plugins. Check the rule list for anything that returns 410 for the URL or for a pattern (regular expression) that matches it. Temporarily deactivating the plugin helps you isolate it.
.htaccessand server configuration. Look for lines containingRedirect gone,RedirectMatch gone, or[G], and forreturn 410in Nginx.
# Find Redirect gone / RedirectMatch gone and RewriteRules with the G flag
grep -n -i -E 'gone|\[([^]]*,)?G(,[^]]*)?\]' /var/www/html/.htaccess
sudo grep -rn "return 410" /etc/nginx/
Multisite: when the site status is the cause
On Multisite, if you open a site that was set to "Deactivate," "Archive," or "Spam" in Network Admin, WordPress core returns a 410. The English screen shows This site is no longer available. (deactivated) or This site has been archived or suspended. (archived or spam) (ms_site_check() in ms-load.php). When you are logged in as a Super Admin, this check is skipped and the site displays normally, so check while logged out.
With WP-CLI, you can list sites by status and restore them (wp site).
# Find deactivated, archived, and spam sites
wp site list --deleted=1 --fields=blog_id,url
wp site list --archived=1 --fields=blog_id,url
wp site list --spam=1 --fields=blog_id,url
# Restore site ID 3 (run only the ones that apply)
wp site activate 3
wp site unarchive 3
wp site unspam 3
Placing wp-content/blog-deleted.php or wp-content/blog-suspended.php lets you replace the screen shown in these cases.
Things to watch out for
- A URL that returns 410 drops out of search results, and the value of external links pointing to it is not passed on. If a replacement page exists, use a 301 redirect.
- Don't use 410 for pages that are only paused. For a temporary outage, use 503 (maintenance).
- Make a copy of the original file before changing
.htaccessor the server configuration.
FAQ
Should a deleted post return 404 or 410?
If you only want it removed from search results, WordPress's default 404 is enough. Google treats 404 and 410 the same. Use 410 when you want to distinguish intentional removals in logs or monitoring.
Can I create a page at a URL that returns 410 later?
Yes. The code in Method 4 only changes the status to 410 when the request is a 404, so once you create a page it displays normally. If you set it up with Redirection, .htaccess, or Nginx, remove that rule first.
Is my 404 page design also used for 410?
With Method 4, your theme's 404 template is used as-is. If Apache or Nginx returns the 410, the server's default error page is shown. To build a 404 page, see How to customize the WordPress 404 page.
Summary
- 410 Gone is a status code meaning "removed on purpose and not coming back"; WordPress returns 404 for deleted posts by default.
- To return a 410, use Redirection,
Redirect gonein.htaccess,return 410in Nginx, orstatus_header( 410 )in PHP, and check withcurl -I. - For an unexpected 410, check the CDN/WAF, redirect plugins, server configuration, and Multisite site status, in that order.
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)