Websites21 min readPublished September 2026

Your site is down, the host says it's fine: first 20 minutes

What the host actually checked before saying "everything looks fine on our end", and how to spend the next twenty minutes ruling out the rest.

The host is probably telling the truth

"Everything looks fine on our end" is a narrow, checkable statement, and it is usually correct. It means the server is up, the account exists, the disk is there and the web server answers. None of that says your site loads.

Four separate layers can take a site off the air, and the host only owns two of them. The network and the domain sit in front of the server. The account limits and the web server are the host's. WordPress, the theme and the thirty plugins sit behind all of it, and a fatal error there produces a dead site on a server that is working perfectly. Then there is a fourth case that fits none of the layers: the site is fine and it is only down for you.

So the answer you got is not a brush-off. It is the first thing crossed off the list. The next twenty minutes are for crossing off the rest, one check at a time, in an order that stops you from making it worse.

Do not start by restoring a backup. It is the most tempting first move and the one that most often destroys the evidence you need - and, if the cause is an intrusion, restores the way back in along with the content. Once you know what broke, a restore is often the fastest way back; it is the timing that is wrong, not the tool.

Minute 0-3: is it down for everyone, or only for you?

Open the site on mobile data, with Wi-Fi switched off, in a private window. If it loads there and not on your laptop, the site is not down. Your route to it is.

This case is common enough to check first, because it looks identical to a catastrophe from where you are sitting. A few failed logins - yours, or a bot using your username - and a brute-force guard drops your address. cPanel's own documentation is blunt about how that looks:

When cPHulk blocks an IP address or account, it does not identify itself as the source of the block. Instead, the login page displays the following warning message: The login is invalid.

Read that again with an owner's eyes. You type the right password, the panel says the login is invalid, and you conclude that someone changed it - that you have been hacked. The actual event was a timer on a counter. The same shape applies inside WordPress if you run a security plugin that limits login attempts, and to office firewalls that block outbound traffic to a newly categorised domain.

Four checks, in order, before you call anyone:

  1. Mobile data, private window. Different IP address, no cached login, no browser extension in the way.
  2. A second person, a different city. Ask someone to open the site and send you a screenshot of whatever appears, including the address bar.
  3. The site versus the dashboard. example.com and example.com/wp-admin can fail independently. Which of the two is broken narrows the cause more than any error message.
  4. The domain, not just the site. Check the registrar for an expiry date and the certificate for its own. A domain that lapsed on Friday behaves exactly like a server that died on Friday.

What does the error page actually say?

Whatever text is on the screen is the cheapest diagnosis available, and most owners skip it because it looks like noise. It is not noise. Each message belongs to a different layer, and the layer tells you who can fix it.

What you seeLayerUsually meansFirst move
Blank white page, or "There has been a critical error on this website"ApplicationPHP fatal error in a plugin or themeLook for the recovery email, below
500 Internal Server ErrorServer running your codeScript died, bad .htaccess, memory exhaustedRead the error log
502 / 504 gateway errorsServerPHP process died or took too longAsk the host about PHP-FPM and timeouts
503 Service UnavailableAccount or serverResource limits, or a maintenance mode that never endedCheck limits, then .maintenance file
508 Resource Limit Is ReachedAccount limitsYour account exceeded its share of the serverSee the limits section below
"Error establishing a database connection"DatabaseWrong credentials, database server down or overloadedAsk the host if the database server answers
DNS_PROBE_FINISHED_NXDOMAIN, "server IP address could not be found"Domain and DNSDomain expired, nameservers changed or wrongCheck the registrar first, the host second
"Your connection is not private", certificate errorsTLSCertificate expired or does not cover this hostnameRenewal, not repair
403 Forbidden on everythingServer or firewallPermissions changed, or a rule is blocking youAsk whether a firewall rule fired

Two rules make this table worth more than a list of causes. Write down the exact wording and the time before you touch anything, because the message often changes once you start poking. And check whether the same message appears on a static file - example.com/robots.txt - since a static file that loads while pages fail puts the fault squarely in PHP, not in the server.

Breakages have sizes. A single failing plugin is one job, a site that has been dead for a week with nobody who knows what changed is a different one, and knowing which you have is what a fixed-price website repair scopes before anyone starts.

Minute 3-10: the white screen has a back door, and it emailed you

If the screen is blank or says the site is experiencing technical difficulties, WordPress has almost certainly already sent you a way back in. Since version 5.2 a fatal error triggers an email containing a private link that gets you into the dashboard with the broken plugin paused.

The core team described the feature when it shipped:

Even in the case where a fatal error would commonly have made the backend completely inaccessible (for example through a so-called "white screen of death"), administrators will now still have the chance to log in and do something about the issue.

Three details decide whether that email is any use to you, and all three are in the source code rather than in any tutorial:

  • It goes to the address in Settings → General, not to whoever is currently panicking. In the code the recipient is the admin_email option, unless a RECOVERY_MODE_EMAIL constant is defined in wp-config.php. On plenty of sites that address still belongs to the agency that built it in 2019.
  • The link is good for a day. The rate limit between recovery emails defaults to DAY_IN_SECONDS, and the link is valid for at least as long as that limit. Miss it, and the next one is not immediate.
  • The subject line is Your Site is Experiencing a Technical Issue, prefixed with your site name. Search for that phrase in every mailbox that might hold it, including spam.

There is one honest limit, and the announcement states it directly: recovery mode works by setting a cookie on your browser, so pausing the broken plugin applies to you alone. "[F]or the other users the site remains in a broken state until the issue has been fixed or mitigated." You get your dashboard back. Your visitors still see the error until you deactivate or fix the extension.

The recovery email never arrived. Now what?

Three reasons, and none of them is a hack. The address is not yours, the handler was switched off, or the site cannot send mail at all - which is ordinary for a site whose mail was never configured beyond PHP's default.

The handler can be disabled by a constant, WP_DISABLE_FATAL_ERROR_HANDLER, and some hosts and performance plugins set it. If it is off, a fatal error produces the old blank page and no email, and nothing is malfunctioning. That is the setting doing what it was told.

Without the email, you still have two moves that need no developer, both through the file manager in your hosting panel or over SFTP:

  1. Rename wp-content/plugins to plugins-off. Every plugin deactivates at once, and a site that comes back is a site with a plugin problem. Two things to know before doing this on a live site. While the folder is renamed, the shop, the forms, the caching and the security plugins are off for visitors too, so on a store treat orders placed in that window as lost and pick the quietest hour you have. And renaming the folder back does not switch the plugins on again: WordPress has already recorded them as deactivated, and licence keys and scheduled jobs in some of them need re-activating by hand. Re-enable them one at a time from the dashboard until it breaks again. The one that breaks it is your answer.
  2. Turn on the log and read the last fatal error. The documented block for wp-config.php writes errors to a file instead of the screen:
php
// Enable WP_DEBUG mode
define( 'WP_DEBUG', true );
// Enable Debug logging to the /wp-content/debug.log file
define( 'WP_DEBUG_LOG', true );
// Disable display of errors and warnings
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

The last line of wp-content/debug.log names the file that died, and the file path names the plugin. That is usually the whole diagnosis.

The WP_DEBUG_DISPLAY line is not optional. Half the advice online says "turn on WP_DEBUG" and stops there, which prints server paths and error text to every visitor - useful reconnaissance for whoever comes next. Log it, do not display it, and turn it off when you are done.

Why can the host be right and your site still be dead?

Because on shared hosting the account limits are designed to take your site down without touching anyone else's. That is not a side effect of the design, it is the stated purpose of it: your account gets a fixed share of the machine, and when it runs out, your visitors get an error while the server carries on serving everybody else.

Most cPanel shared hosting runs CloudLinux, whose documentation describes the mechanism plainly:

Each LVE limits amount of entry processes (Apache processes entering into LVE) to prevent single site exhausting all Apache processes. If the limit is reached, then mod_hostinglimits will not be able to place Apache process into LVE, and will return error code 508. This way very heavy site would slow down and start returning 508 errors, without affecting other users.

The default entry process limit in that documentation is 20 - roughly, twenty simultaneous requests to PHP, with SSH sessions and cron jobs counted in. A bot sweep, a burst of traffic or one slow query can spend that. And when the limit that gets hit is memory or process count instead, the same page says visitors "will receive 500 or 503 errors that server cannot execute the script", which is why a resource problem so often arrives disguised as a code problem.

From the host's monitoring, this is a healthy server. From your chair, the site is gone. Both readings are accurate, which is why "is everything OK on your end?" is the wrong question. These are the right ones:

text
Hi - my site has been returning <exact error> since <time, with timezone>.
Could you check, for my account specifically:

1. Did the account hit any resource limits in that window - entry processes,
   memory, CPU, I/O? If so, which one and how often?
2. What are the last entries in the error log for this account?
3. Has any firewall or brute-force rule blocked my IP address recently?
   My address is <check whatismyip.com>.
4. Were there any changes on your side in the last 48 hours - PHP version,
   server migration, security rules?
5. Do you keep a backup of this account, from when, and is restoring it
   chargeable?

I am not asking whether the server is up. I can see that it is.

Every one of those questions has a factual answer that lives in the host's tools and not in yours. Sending them in a single message also skips two rounds of first-line replies.

Minute 10-20: what if the site works for you but not for your visitors?

Then you are not looking at what they are looking at. This is a real failure mode with a specific cause, and it is the one case in this list where "it works for me" is the most alarming possible answer.

Google's documentation on hacked content describes the pattern:

Redirects: Hackers might inject malicious code to your website that redirects some users to harmful or spammy pages. The kind of redirect sometimes depends on the referrer, user agent, or device. For example, clicking a URL in Google Search results could redirect you to a suspicious page, but there is no redirect when you visit the same URL directly from a browser.

Injected code that only fires for strangers can keep the owner unaware indefinitely, because nothing in the owner's own view of the site ever changes. You type the address directly, you are logged in, you are on a desktop - three conditions that switch the redirect off. Your customers arrive from a search result on a phone and land somewhere else entirely.

Four ways to see what they see, none of which takes longer than a minute:

  1. Arrive from search. Find the page in Google and click it, rather than typing the address.
  2. Use a phone, on mobile data, logged out. Device and referrer are the two conditions the injected code reads most often.
  3. Inspect the URL in Search Console. The URL Inspection tool renders the page as the crawler sees it - the help page describes it as a way to "See a screenshot of how the Google-InspectionTool sees the page" - and the live test shows the current state rather than the indexed one.
  4. Search for your own site in Google. Titles in a language you do not publish in, or pages you never wrote, are the classic signature.

If any of those shows something you did not put there, stop treating this as a breakage. It is an incident, and the next section applies.

When does a breakage become an incident?

Rarely, and later than the panic suggests. Most sites that go dark go dark for dull reasons - a plugin update, an expired domain, a resource limit, a certificate nobody renewed - and for most owners the checks above end there.

The line is crossed when you find something that a bug cannot explain: an administrator account you did not create, redirects that only strangers get, pages in search results you never wrote, or a warning from Search Console. At that point the priority changes from "get it back up" to "find out how they got in".

Speed alone is the wrong instinct here, because an intrusion is rarely one file. Whoever got in almost always leaves a way back - a backdoor in a file nobody looks at, or an administrator account that looks like one of yours - precisely so that the obvious repair does not end the visit.

That is the reason restoring a backup so often fails as a fix. Four things survive it:

  • The backup itself predates your discovery, not the intrusion, so the backdoor is usually inside the copy you are restoring.
  • A malicious administrator lives in the database, so restoring files leaves it in place.
  • Payloads hide where a restore does not look, including mu-plugins, which load automatically and do not show in the default plugin list - they sit behind a separate Must-Use tab that most owners have never opened.
  • The way in - the unpatched component - is still open, and it was found by an automated scan that will come back.

A host answering exactly this question on the WordPress support forum summed up the mechanism in one line: what tends to survive is "leftover backdoors outside the WP install, or a hidden admin user in the database".

One more thing, because it removes a false comfort. Most hacked sites are never flagged at all: an injected redirect that only fires for strangers can run for months without a browser warning or a blacklist entry. The absence of a red warning proves nothing. And when a site does get flagged, most visitors do what the warning tells them to and leave, so the traffic goes at once.

If the entry point turns out to be a plugin that was out of date, the timeline is worth understanding, because the patch reaches your site later than you think.

Where does do-it-yourself end?

At the point where fixing it means reading code and editing database rows. Up to that line an owner can do a great deal; past it, guesswork does damage that costs more than the original problem.

WordPress's own documentation does not soften this:

Find and remove the hack. This will be the most daunting part of the entire process. [...] How you approach the problem will be determined by your own technical aptitude working with websites and web servers.

Safe for an owner, in any order, and all of it useful even if you hand the job over afterwards:

  • Change the passwords for every door, not just wp-admin: hosting panel, FTP and SFTP, domain registrar, and the email account those recoveries go to. Leave the database password for last, and treat it as a two-part change. The site reads that password from wp-config.php, so changing it in the hosting panel alone takes the site down with "Error establishing a database connection" until the same new value is in DB_PASSWORD
  • Replace the secret keys in wp-config.php using the WordPress key generator, which forces every logged-in session off the site - yours included, along with any session that is not yours. Download a copy of the file before editing it, since one stray character in wp-config.php takes the whole site down
  • Read the list of administrators and note anything you cannot account for
  • Update WordPress, plugins and themes - after the passwords, not before, and after you have copied the current files and database somewhere aside, because an update can finish off a site that a stale plugin was holding together
  • Run two free scanners: one plugin-based, one remote crawler, because they look for different things
  • Set up Search Console, so the next time you hear it from Google rather than from a customer

Three things to avoid while the adrenaline is up. Do not clean database tables by hand on a live site: plugins legitimately use the same functions that malware does, and even the cleanup vendors' own guides tell readers who are not comfortable editing PHP or database tables to get a professional involved rather than break the site. Do not delete files you cannot identify. And do not move to a new host to escape the problem, since a migration copies the infection and the backdoor along with everything else, then costs you the logs that would have shown when it started.

What does it cost to fix?

Less than the fear suggests, and priced by speed rather than by effort. Public one-off cleanup prices from specialist vendors start around $40 and cluster between roughly $95 and $250 - advertised list prices in US dollars, checked in August 2026, and not a survey of what anyone actually paid.

Urgency is the real multiplier. One WordPress repair shop lists the same job at $99 within 24 hours, $149 within 12 and $299 within 4. The work does not change. The queue position does. That pattern is not specific to hacked sites - the same three inputs set the price of any repair job quoted in a hurry.

Two costs surprise people, so they are worth knowing before you are the one being surprised:

  • A security subscription bought today does not fix today's hack. SiteLock's plan comparison marks expert removal as not available on its entry plan, and on the paid tiers the unlimited expert removal "excludes pre-existing infections" - clearing those is a separate product. Jetpack says plainly that its scanner "is not designed to fully clean up sites infected before it was active". These are the products people buy at exactly the wrong moment.
  • Restoring a backup can be a paid service. HostGator prices its recovery service at $49, and Namecheap charges a $15.00 service fee to recover data for a suspended or terminated account. Ask before you assume a restore is free and instant.

Where the line falls for us: a confirmed infection belongs with a specialist cleanup vendor - a cheap, crowded market whose vendors sell a reinfection warranty as part of the product. The jobs worth a fixed price are the other ones - a site that broke after an update, a site that has been dead since the developer stopped answering, a site nobody can safely change. That is what a website fix covers, and you can size it yourself before talking to anyone.

What can you do today so the next twenty minutes are boring?

Five things, none of which needs a developer, all of which turn a bad hour into a short one. Do them while nothing is broken - during an outage you will not have the patience.

  1. Check who gets the emergency email. Settings → General shows the address WordPress writes to when the site dies. If it is not read daily by someone who can act, change it, or set RECOVERY_MODE_EMAIL in wp-config.php to an address that is.
  2. Write down the four sets of credentials. Domain registrar, DNS, hosting panel, WordPress admin. Most outages that last days are access problems, not technical ones: the repair waits on a login, not on a diagnosis.
  3. Set up Search Console. It is free, it takes ten minutes, and it is how you find out about a conditional redirect before your customers do.
  4. Keep a list of what is installed. Plugins, themes, versions, and who put them there. Without it, every security headline is unanswerable and every diagnosis starts from zero.
  5. Get an external uptime check. Any monitor that watches from outside your network catches the outage that your own browser cache is hiding, and it also gives you a timestamp - the single most useful thing to put in the first message to your host.

A dead site announces itself. The failures worth fearing are the quiet ones, which is the same lesson as an automation that stops firing without telling anyone: by the time it is obvious, it has been broken for a while.

Sources

Site down, or broken since the last update? Fix S — $300, 2 business days, fixed price.

Get my quote in 24h

Written by the Fixmation team.