Cookies are blocked or not supported in WordPress

You submit your WordPress login and get back: Cookies are blocked or not supported by your browser. You must enable cookies to use WordPress. This article walks through the usual causes in order of likelihood, shows you how to verify each one, and tells you exactly what to do per case.

What this error actually means

WordPress places a short-lived probe cookie called wordpress_test_cookie when it renders wp-login.php, and then checks for it on the POST back. If the probe cookie is not present when you submit the form, WordPress refuses to run wp_set_auth_cookie() and shows the error. It is a safety interlock: there is no point writing the three real authentication cookies (wordpress_[hash], wordpress_sec_[hash], wordpress_logged_in_[hash], documented in the WordPress handbook) if the browser is not going to accept them on the next request.

The message is therefore a symptom, not a diagnosis. In practice the browser is almost always willing to accept cookies. The question is what is stopping the test cookie from making the round trip.

Common causes, ordered by likelihood

  1. You are loading wp-admin inside an iframe or a third-party context. SaaS dashboards, site builders, and "preview in a modal" flows embed WordPress inside an iframe on a different domain. Browsers apply SameSite=Lax by default, and MDN's SameSite reference is explicit: a Lax cookie is only sent on top-level safe navigations. A POST from inside an iframe on another domain is neither, so the test cookie is dropped.
  2. A browser extension or hardened privacy mode is blocking the probe. Brave's strict Shields, uBlock Origin's cosmetic filters, the "delete cookies on exit" profiles in Firefox, and private/incognito windows with third-party extensions loaded all break the probe silently.
  3. WP_HOME / WP_SITEURL do not match the URL in your browser bar. The auth cookies are scoped to the domain WordPress thinks it is. If you reach https://www.example.com/wp-login.php but WP_HOME is https://example.com, the browser gets a cookie for example.com and posts back on www.example.com. From the browser's perspective the probe cookie is missing.
  4. A cache or security plugin is stripping Set-Cookie headers on wp-login.php. Full-page cache plugins occasionally cache the login page for anonymous visitors, and security plugins sometimes rewrite responses. Either can silently remove the Set-Cookie: wordpress_test_cookie=... header.
  5. Something is sending output before the headers. A stray newline, a UTF-8 BOM, or a echo/var_dump in wp-config.php, a must-use plugin, or an active theme's functions.php can trip PHP's "headers already sent" state. WordPress detects this and explicitly returns the blocked-cookies error instead. This is the classic "unexpected output" variant.

Diagnose which cause applies

Open your browser's DevTools (F12), switch to the Network tab, reload wp-login.php, and look at the response for that request. Then submit the form and look at the POST.

  • Does the GET response contain Set-Cookie: wordpress_test_cookie=...? If not, something on your site is suppressing it. Jump to cause 4 or 5.
  • Does the Cookie tab on the POST request include wordpress_test_cookie? If not, the browser received it but did not send it back. Jump to cause 1, 2, or 3.
  • Does document.cookie in the Console show the probe after a simple page load? If it does and it still is not sent on POST, you are almost certainly in a cross-site iframe or SameSite context (cause 1).

If the POST response body literally contains the string "Cookies are blocked due to unexpected output", you are in cause 5. WordPress calls that variant out explicitly, so you do not need to guess.

Fix per cause

Cause 1: iframe or third-party context

Open wp-login.php in a new top-level tab instead of inside the embed. If the host application is a SaaS that always wraps admin screens in an iframe, this is a structural limitation of Lax cookies; the only clean fix is to log in once in a top-level tab and then return to the embed. You will know it worked when the URL bar shows wp-admin/ after login instead of bouncing back to wp-login.php.

Cause 2: browser extension or hardened mode

Try a different browser profile with no extensions, or a regular (non-private) window. If that works, the cause is in the current profile. In Brave, open Shields on the site and set cookies to "Allow all cookies" for example.com. In Firefox, "Enhanced Tracking Protection" for the site can be switched off per-site from the shield icon in the address bar. Verify by retrying the login in the modified profile: a successful login rules out the extension stack.

Cause 3: domain or HTTPS mismatch

Check wp-config.php for WP_HOME and WP_SITEURL. If they are absent, check the siteurl and home options in the database. Both values must match the exact URL you hit in the address bar, including the www or absence of it and the https:// scheme. If the browser also shows a broken padlock or console warnings about insecure subresources, the same incomplete migration may be causing mixed content warnings.

// wp-config.php, for a site served on https://www.example.com
define( 'WP_HOME',    'https://www.example.com' );
define( 'WP_SITEURL', 'https://www.example.com' );

After saving, clear any browser cookies scoped to the old hostname and reload wp-login.php. You will know it worked when you can complete the login without bouncing and DevTools shows the auth cookies set on the exact domain in the URL bar.

If you run a multisite with mapped domains, you may also need to stop forcing COOKIE_DOMAIN, which is documented in the wp-config reference as a single value. Multisite with domain mapping needs the default behavior, not a hard-coded domain.

Cause 4: cache or security plugin stripping the header

Rename the plugin you suspect under wp-content/plugins/ via SFTP or the hosting file manager. Start with full-page caches (wp-super-cache, w3-total-cache, wp-rocket, litespeed-cache) and WAF-style security plugins (wordfence, wp-cerber, all-in-one-wp-security-and-firewall). Renaming the directory forces WordPress to treat the plugin as missing, which deactivates it without needing dashboard access.

Retry the login after each rename. You will know you found the culprit when the login succeeds and DevTools shows the Set-Cookie: wordpress_test_cookie=... header returning on the GET. Restore the plugin directory afterwards and contact the plugin vendor: a correctly configured cache should never cache wp-login.php, and a correctly configured WAF should never rewrite Set-Cookie headers on it.

Cause 5: unexpected output (BOM, whitespace, stray echo)

Rename your active theme's directory so WordPress falls back to a core theme (twentytwentyfive or whichever is bundled with your version). Retry login. If that fixes it, the problem is in the theme's functions.php or an included file. If it does not, rename wp-content/mu-plugins next, then check wp-config.php for any line that starts before <?php or comes after a trailing ?> that is followed by whitespace or a newline.

The fastest way to find a BOM is to open the suspect file in a hex-aware editor and look for the bytes EF BB BF at position zero. Remove them and save as UTF-8 without BOM. You will know it worked when wp-login.php returns a clean response body without the "due to unexpected output" phrasing and the auth cookies round-trip successfully.

When to escalate

If you have worked through all five causes and the error is still there, collect the following before asking for help, so whoever looks at it next does not have to start from zero:

  • WordPress version, PHP version, active theme, and an exact list of active plugins (from wp plugin list --status=active or the Plugins screen)
  • The full wp-config.php with secrets redacted, showing WP_HOME, WP_SITEURL, and any COOKIE_* constants
  • A DevTools Network export (HAR) for one login attempt, covering both the GET wp-login.php and the POST
  • The response body of the failing POST, specifically whether it contains the words "due to unexpected output"
  • Whether the site runs behind Cloudflare, a load balancer, or any reverse proxy, and which hosting tier
  • The output of curl -I https://www.example.com/wp-login.php showing the response headers

If you are stuck after that, read why you cannot log in to WordPress to confirm you are in the right article: the sibling WordPress login redirect loop covers the case where the probe cookie works fine but the authenticated session still does not stick, and no access to wp-admin without an error covers situations where you never see the WordPress login screen at all. If you land on the dashboard but then get "Sorry, you are not allowed to access this page", the login has already succeeded and your problem is a capability check, not a cookie one.

How to prevent it from happening again

  • Keep WP_HOME and WP_SITEURL pinned in wp-config.php so they cannot drift out of sync with the domain the browser actually hits.
  • Exclude wp-login.php and wp-admin/* from every caching layer you add, whether a plugin, a CDN page rule, or a reverse proxy.
  • Before committing edits to wp-config.php or functions.php, save as UTF-8 without BOM and make sure there is no whitespace or newline before <?php and no closing ?> at all.
  • Avoid embedding wp-admin inside an iframe on a different domain; if the host app must do it, open login in a top-level tab and rely on the existing session afterwards.

Locked out of wp-admin too often?

Login and access issues usually come down to changes, conflicts or security rules. WordPress maintenance reduces surprises with controlled updates and checks.

See WordPress maintenance

Search this site

Start typing to search, or browse the knowledge base and blog.