You type your password, press Log In, and wait for your dashboard and it never shows up.
Instead, you land right back on the login screen with a yellow warning across the top. If it’s the “cannot modify header information headers already sent by” error, you’re also staring at two file paths and two line numbers that seem to be written for someone else.
We’ve watched this login loop swallow entire afternoons, and the cause is almost always something tiny, like a single blank line.
TL;DR: Fix the file named after “output started at”, because that’s where something printed too early, usually a blank line, a hidden byte called a BOM, or an early error message. Leave the second file alone, especially wp-includes/pluggable.php, back up before you edit, and test your login and redirects once the warning is gone.
Why you’re stuck in a login loop
Every page your site sends has two parts: hidden instructions called headers, and then the page you see. The headers always have to leave first.
Those headers carry messages like “save this login cookie” or “send this person to the dashboard.” If even one invisible character prints before them, PHP refuses to send them at all.
So WordPress checks your password, tries to save your login cookie, finds the door already shut, and sends you back to the login screen. Redirects, carts, and sessions break the same way, since they all depend on headers.
Headers also carry browser security instructions through WordPress security headers, though adding those won’t fix the premature output causing this warning.
📝 Note: This is only a warning, so your site can look almost normal while logins and redirects quietly fail. That’s why people sometimes live with it for weeks.
How to read the warning
The warning gives you two file paths, and you only need to fix the first one. Here’s what a typical message looks like:
Warning: Cannot modify header information - headers already sent by
(output started at /home/user/public_html/wp-config.php:1)
in /home/user/public_html/wp-includes/pluggable.php on line 1450
The path after “output started at” is the culprit. That’s the file and line where something printed too early.

The path at the end is just where WordPress noticed. It’s very often wp-includes/pluggable.php, the core file that handles logins and redirects, so leave it alone, since editing it won’t help and WordPress replaces it on every update anyway.
Use this table to see what your culprit path is telling you:
| “Output started at” points to | What’s usually going on |
|---|---|
| wp-config.php:1 | A hidden BOM or a blank line before the opening tag |
| Your theme’s functions.php | A pasted snippet with stray spaces or a closing tag |
| A file in wp-content/plugins | A plugin printing text or an error too early |
| A file in wp-content/mu-plugins | A must-use plugin you can’t switch off from the dashboard |
| advanced-cache.php or object-cache.php | A leftover file from an old caching plugin |
| A theme template like page.php | A redirect running after the page has started loading |
📝 Note: A line number of 1 almost always means the problem is in the very first few characters of the file. That makes your search much smaller.
Backup before you change anything
You’re about to edit a file that runs on every page load, so give yourself a way back first. One small slip can turn a warning into a site that won’t load at all.

- Take a full backup or work on a staging copy. If you can’t do either, at least download the culprit file and keep the original safe.
- Be extra careful with wp-config.php. It holds your database details and security keys, so a broken edit there can lock you out completely.
BlogVault stores backups off your server and restores your site in one click, which is exactly what you want if an edit goes wrong.

📝 Note: Change one thing at a time and test after each edit. Otherwise, you won’t know which change fixed the problem or which one caused a new one.
Getting to the file when you’re locked out
- Since the login loop keeps you out of the dashboard, you’ll open the file from outside WordPress.
- Use your host’s file manager. You’ll usually find it in cPanel or a similar control panel, and it works well for most people.
- Use SFTP if you prefer an FTP app. Either way, follow the “output started at” path to the exact file.
- Download a copy before you edit. That untouched copy is your undo button.
Not comfortable editing files? Send your host or developer the full warning, both file paths, and any recent changes. They can usually find the problem in minutes.
If fixing the named file removes the warning but you still can’t access your dashboard, follow these steps for recovering access to wp-admin.
📝 Note: Never edit PHP files in Word or Google Docs. Those apps can add the very hidden characters that cause this warning, so use a code editor or your host’s file editor.
Clean out the invisible characters
- Invisible characters cause more of these warnings than anything else we see. That’s why a file can look spotless and still break your login.
- Delete anything before the opening PHP tag. The file should start with
<?php, with no blank line or space in front of it. - Remove the closing tag from PHP-only files. If functions.php or wp-config.php ends with
?>, you can delete it along with any spaces after it, which WordPress’s own coding standards actually recommend. - Save the file as UTF-8 without BOM. A BOM, or byte order mark, is a hidden marker some editors add to the start of a file, and PHP sends it out even though you can’t see it.
In VS Code or Notepad++, choose plain “UTF-8” instead of “UTF-8 with BOM” when you save. If the warning says line 1 and the file looks clean, assume there’s a BOM until you’ve ruled it out.
📝 Note: Comfortable with a terminal? Run
head -c 5 wp-config.php | xxd. A clean file starts with3c3f 7068 70, while a file with a BOM starts withefbb bf.
Look for code that prints too early
- No hidden characters? Then the early output is coming from the code itself. Check the area around the line number in the warning.
- Look for anything that prints text. That includes
echo,print,var_dump, stray HTML, or a debugging line someone forgot to delete. - Check recently pasted snippets first. Copied code often brings an extra blank line or closing tag with it, and it’s the most common trigger we see after a quick tweak to functions.php.
- Move redirects out of page templates. If
wp_redirect()sits inside a file like page.php, it runs too late, so move it into a function hooked totemplate_redirectinstead. - Fix the first error message, not the last. An early notice from a plugin can print before the headers, and this warning follows right behind it, so fixing that first notice usually fixes both.
📝 Note: After editing a PHP file over SSH, run
php -l filename.phpto catch syntax errors. It won’t spot a BOM, but it will stop a typo from taking your site down.
Keep errors away from your visitors
Warnings on the page expose your server paths, and they can also be the output breaking your headers. Sending them to a private log fixes both problems.
Add or update these lines in wp-config.php, just above the line that says to stop editing:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Errors now go into debug.log inside your wp-content folder. Read it from the top to find the first warning in the chain.
Switch WP_DEBUG back to false when you’re done. Otherwise, the log keeps growing in the background.
📝 Note: If the warning vanishes as soon as you hide errors, the cause is still there. Check debug.log and fix the original notice.
Track down the plugin or theme behind it
When the culprit path runs through wp-content/plugins or wp-content/themes, the folder name right after it tells you exactly who to suspect.
- Update the suspect first. Developers often fix this kind of bug quickly.
- Switch it off to confirm. Deactivate it on staging, or rename its folder in your file manager if you’re locked out, such as changing “plugin-name” to “plugin-name-off.”
- Report it if the warning disappears. Send the developer the full warning and both file paths.
- Rename must-use plugins and drop-ins directly. Files in wp-content/mu-plugins don’t appear on the Plugins screen, and a leftover advanced-cache.php or object-cache.php from a removed caching plugin is a sneaky source of this error.
📝 Note: Don’t edit a third-party plugin’s files to fix this yourself. The next update will overwrite your change, and the warning will come right back.
A word about ob_start()
You’ll find advice online suggesting ob_start() or output buffering, and it often does make the warning disappear. Buffering holds back everything until the page is complete, so headers still get out first.
- The early output is still in your file, though. That stray BOM or debugging line can cause a different problem later.
- Remove the early output itself for a reliable fix. Save buffering for developers who have a specific reason to use it.
📝 Note: Some hosts turn on buffering at the server level, which is why a site can work on one host and show this warning on another. A warning that appears right after a host move usually means the problem was there all along.
Make sure the loop is really gone
- Go back to where this started: log out, then log back in. If you reach your dashboard, the main fix worked.
- Test the other features headers control. Submit a form that redirects to a thank-you page, and if you run a store, add something to your cart and start checkout.If your site is configured to redirect HTTP to HTTPS, test that redirect too and confirm it reaches the secure page without looping.
- Check debug.log one more time. If the warning returns, compare the new “output started at” path with the old one, since a second file may have been hiding behind the first.
A broken RSS feed may start working again too, since the same stray output was breaking its format.
📝 Note: Clear your browser cookies and your caching plugin’s cache before testing. Old cookies can keep a login loop going even after the cause is fixed.
When it might be something more serious
This warning almost never means your site has been hacked. Whitespace, BOMs, and plugin bugs cause the vast majority of cases.
Still, read the culprit file carefully. Code you don’t recognize, long strings of random characters, or links and scripts you never added point to a separate security problem.

Scan the site if something looks off. Keep your backup safe, then use a WordPress malware scanner such as MalCare, which checks your files, plugins, themes, and database.
📝 Note: A malware scan won’t fix a stray space or BOM. Save it for when you find code that clearly doesn’t belong.
FAQs
Will this warning hurt my SEO?
Not directly, but the side effects can. Broken redirects and warnings showing on public pages affect how visitors and search engines experience your site.
Why did this appear when I didn’t change anything?
Something usually changed in the background. A plugin may have updated automatically, or your host may have upgraded PHP, which can surface notices older code never showed before. If activity logging was already enabled, check your WordPress activity log for plugin updates or theme changes around the time the warning first appeared.
Can I make it go away by turning off errors?
You can hide it from visitors, but logins and redirects will keep failing. The early output stays until you remove it.
Is it safe to replace wp-config.php with a fresh copy?
Only if you carry over your real database details and security keys. Without them, the site breaks entirely, so editing the existing file is usually safer.
Why does the warning keep coming back?
Either more than one file prints early, or something keeps restoring the old file. Compare each new “output started at” path, and check whether a plugin update or deployment process is overwriting your fix.
Conclusion
That login screen that kept sending you back almost always comes down to one blank line, one hidden byte, or one message that printed a moment too soon. Follow the “output started at” path, protect the file with a backup, and remove the stray output right where it starts.
Once you’re back on your dashboard, keep errors flowing into a private log, so the next time something prints too early, you’ll catch it there long before your visitors do.



