2026年11月12日

2026年11月12日

Returning HTTP 451 Unavailable For Legal Reasons in WordPress

This article is a localized edition of the Japanese original. Read the Japanese original

What HTTP 451 means

451 Unavailable For Legal Reasons is a status code indicating that access to a resource is blocked in response to a legal demand. It is defined in RFC 7725. The key points of the RFC:

  • The response body should explain the demand (who made it, the law it is based on, and which people and resources it covers).
  • The entity blocking access should identify itself with a URL in a Link header using rel="blocked-by". It identifies the entity actually doing the blocking, not the one that demanded it.
  • The server returning 451 is not necessarily the origin server; it may be an intermediary such as an ISP or a cache provider.
  • A 451 response is cacheable unless explicitly specified otherwise.

How it differs from similar status codes:

Code Meaning
403 Forbidden Access denied for lack of permission
404 Not Found Not found (no reason given)
410 Gone Deliberately removed and will not come back
451 Unavailable For Legal Reasons Access blocked for legal reasons

WordPress core never returns 451 on its own, but its list of status descriptions (get_status_header_desc()) includes 451, so you can return it with status_header( 451 ) or wp_die().

When your site returns 451: finding where it comes from

A 451 can come from the server, a CDN, a WAF, a plugin or a network provider. For a URL that returns 451 from outside, check in this order.

1. Look at the headers

curl -sI https://example.com/problem-page/

A Link: <...>; rel="blocked-by" header identifies the blocking entity if present. The Server header and any CDN-specific headers also give clues about who responded.

2. Ask the origin server directly, bypassing the CDN

Log in to the server and send a request to itself. --resolve only overrides name resolution, so certificate validation still happens as usual.

curl -sI --resolve example.com:443:127.0.0.1 https://example.com/problem-page/
  • If this returns 200, the 451 is coming from outside the origin server (a CDN, WAF, network provider, etc.). Check that provider's dashboard or contact them.
  • If this also returns 451, the cause is in the server configuration or in WordPress.

3. Search the logs and configuration

# Requests answered with 451 in the access log (in combined format the 9th field is the status)
sudo awk '$9 == 451' /var/log/nginx/access.log | tail -n 20
sudo awk '$9 == 451' /var/log/apache2/access.log | tail -n 20

# Does the web server config return 451 anywhere?
sudo grep -rn '451' /etc/nginx/ /etc/apache2/ 2>/dev/null

# Does any WordPress code return 451?
grep -rnE '451|Unavailable For Legal' /var/www/html/wp-content --include=*.php
grep -n '451' /var/www/html/.htaccess

If you find nothing, contact your hosting provider.

Taking a page down in response to a legal demand

These are the steps for blocking a specific page after a court order or a formal takedown request from a rights holder. Consult a lawyer or other professional on whether to comply and how much to block; this section covers only the technical steps.

1. Revert the post to a draft

First, unpublish the post itself. If you only make the URL return 451 while the post stays published, its content can still be fetched through the REST API (/wp-json/wp/v2/posts/<ID>), feeds and sitemaps.

wp post update 123 --post_status=draft

(Replace 123 with the post ID. In the admin, change the post's status to Draft in the editor and update it.)

The URL now returns 404. If you do not need to give a reason, you can stop here.

2. Return 451 for the blocked URL

To show visitors that the page is blocked, return 451 using one of the following. Each points to a notice page (/legal-notice/ in the examples) with rel="blocked-by". Create the notice page first.

From WordPress (mu-plugin)

This works even where you cannot change the server configuration. Save it as wp-content/mu-plugins/legal-block-451.php.

<?php
/**
 * Plugin Name: Legal Block 451
 * Description: Returns 451 for URLs taken down in response to a legal demand.
 */

add_action( 'template_redirect', function (): void {
    if ( ! is_404() ) {
        return;
    }

    // Paths of the taken-down URLs (no leading or trailing slash)
    $blocked = array(
        'blocked-post',
    );

    global $wp;
    if ( ! in_array( $wp->request, $blocked, true ) ) {
        return;
    }

    $notice = home_url( '/legal-notice/' );
    header( 'Link: <' . esc_url_raw( $notice ) . '>; rel="blocked-by"' );

    wp_die(
        '<p>This page has been taken down in response to a legal demand. See the <a href="' . esc_url( $notice ) . '">notice</a> for details.</p>',
        '451 Unavailable For Legal Reasons',
        array( 'response' => 451 )
    );
}, 1 );
  • It only acts on requests that end up as 404 after the post was reverted to draft, so published pages are not affected.
  • The priority is 1 so it runs before core's redirect_canonical() (priority 10), which might otherwise redirect to a similar URL.
  • wp_die() also sends no-cache headers (Cache-Control: no-cache, must-revalidate, max-age=0, no-store, private).

Tested as of October 2026 on WordPress 6.x with PHP 8.3: the URL returns 200 while published, and 451 with the Link header after reverting to draft, while other non-existent URLs still return 404.

From Nginx

Put this in the server block. An internal redirect via error_page does not carry over headers added in the original location, so add the Link header in the location that serves the notice HTML. Without always, add_header does not apply to 451 responses.

location = /blocked-post/ {
    return 451;
}

error_page 451 /451.html;
location = /451.html {
    internal;
    add_header Link '<https://example.com/legal-notice/>; rel="blocked-by"' always;
}

/451.html is an explanatory HTML file in the web root. Apply the change by checking the syntax with sudo nginx -t and then running sudo systemctl reload nginx. Note that Nginx sends no reason phrase in the status line, just HTTP/1.1 451.

From Apache (.htaccess)

Place this above # BEGIN WordPress. When mod_alias Redirect is given a status outside the 300 range, the target URL is omitted (Apache manual).

ErrorDocument 451 /451.html

<IfModule mod_headers.c>
    Header always set Link "<https://example.com/legal-notice/>; rel=\"blocked-by\"" "expr=%{REQUEST_STATUS} == 451"
</IfModule>

Redirect 451 /blocked-post/
  • Redirect matches by prefix, so every URL starting with /blocked-post/ is affected.
  • Header requires mod_headers to be enabled (sudo a2enmod headers).

The Nginx and Apache examples were tested on the official Docker images (Nginx 1.30.x, Apache 2.4.x) and return 451 with the Link header.

3. Verify

curl -sI https://example.com/blocked-post/ | grep -iE '^(HTTP|link)'

If HTTP/... 451 and Link: <...>; rel="blocked-by" appear, the configuration works.

Operational notes

  • Caching: under RFC 7725, a 451 response is cacheable. If you use a page cache or CDN, purge the URL after setting this up, and purge it again when the demand is lifted and you republish.
  • Notice page: explain, as far as you can, which demand the block is based on. If you cannot disclose the demand, you can keep the text short, or simply leave the URL as a 404 instead of 451.
  • Lifting the block: remove the 451 configuration, then republish the post.
  • Search results: according to Google, URLs returning a 4xx (other than 429) are not indexed, and already indexed URLs are removed. Even for a temporary block, the page does not return to search results until it is crawled again after republishing.

Summary

  • 451 indicates that access is blocked in response to a legal demand (RFC 7725). The rel="blocked-by" Link header identifies the blocking entity.
  • If you see a 451, find its source by checking the headers, a request that bypasses the CDN, and then the logs and configuration.
  • To take a page down, first revert the post to draft so it also disappears from the REST API and feeds, then return 451 for the URL.
  • Return it with a WordPress mu-plugin, Nginx return 451 or Apache Redirect 451. Afterwards, verify with curl -I and purge caches.

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲