Skip to content
Skip to main content
Ahosting Logo
  • Hosting
    • WordPress Hosting
      Fast, secure hosting for WordPress sites
    • Web Hosting
      Reliable, affordable hosting for sites
    • FFMpeg Hosting
      Fast hosting for FFmpeg projects
    • Reseller Hosting
      Start hosting biz with white-label plans
    • VPS Hosting
      Scalable VPS with full control & power
    • Dedicated Server
      High-power servers for max security
    • WooCommerce Hosting
      Fast hosting for WooCommerce shops
  • Domain
    • Register a Domain
      Secure your domain name in minutes
    • Domain Transfer
      Move domains to Ahosting with ease
    • Premium SSL Certificate
      Enterprise SSL to build customer trust
  • Support
    • Submit A Ticket
      Expert 24/7 help from our support team
    • Abuse Report
      Report abuse to keep network safe
    • Knowledge Base
      Quick answers via step-by-step guides
  • Company
    • Blog
      Expert articles to power your online growth
    • Compare Hosts
      Side-by-side comparison
    • Datacenter
      Secure, high tech datacenter for hosting
    • About Us
      Learn about our mission, values & team
    • Contact Us
      Contact sales for plans, pricing & advice
    • Sitemap
      Find info fast with our clear site map
My Account
Ahosting Logo
  • Hosting
    • Web Hosting
    • WordPress Hosting
    • FFMpeg Hosting
    • Reseller Hosting
    • VPS Hosting
    • Dedicated Server
    • WooCommerce Hosting
  • Domain
    • Register a Domain
    • Domain Transfer
    • Premium SSL Certificate
  • Support
    • Knowledge Base
    • Abuse Report
    • Submit A Ticket
  • Company
    • About Us
    • Contact Us
    • Blog
    • Sitemap
    • Datacenter
  • Legal
    • Privacy Policy
    • Terms of Service
    • Acceptable Use Policy
    • Service Level Agreement
    • Resource Abuse Policy
My Account

AHosting Blog

Author: Matt Chrust

Matt Chrust

Director of Business Development, AHosting Matt has led business development at AHosting since the company’s founding in 2002. He writes about WordPress hosting infrastructure, server performance, and the evolving requirements of WordPress sites at scale.
  • Problems Auto-Updating Plugins and Themes? It Is a Filter Test, Not a Server Fault

    Problems Auto-Updating Plugins and Themes? It Is a Filter Test, Not a Server Fault

    • Problems Auto-Updating Plugins and Themes: What the Warning Actually Tests
    • The Three Results of the Problems Auto-Updating Plugins and Themes Check
    • Why Site Health Reports Problems Auto-Updating Plugins and Themes as Critical
      • What the test sends through the filter
      • Why the dashboard switch stops meaning anything
      • Filter patterns that trip the check, and ones that do not
    • Finding the Code Behind Your Problems Auto-Updating Plugins and Themes Warning
      • Constants that change what the dashboard shows
    • What the Problems Auto-Updating Plugins and Themes Check Cannot See
      • Why the filter matters for security
    • Fixing Problems Auto-Updating Plugins and Themes on AHosting
      • Replay the result before you change anything
      • When to open a ticket
    • Frequently Asked Questions: Problems Auto-Updating Plugins and Themes
      • Why won't my WordPress plugins update in 2026 when Site Health reports problems auto-updating plugins and themes?
      • Is it safe to ignore the problems auto-updating plugins and themes warning if I update plugins by hand?
      • Does the problems auto-updating plugins and themes warning mean my cron or file permissions are broken?
      • Critical vs recommended in 2026: which problems auto-updating plugins and themes result is worse?
      • Can AHosting support help me find which plugin is behind the problems auto-updating plugins and themes warning?
      • On AHosting WordPress hosting, auto_update_plugin filter vs plugins_auto_update_enabled filter in 2026: which switches updates off?
      • How do I clear the problems auto-updating plugins and themes warning on an AHosting WordPress plan without editing core files?
      • What does DISALLOW_FILE_MODS do to the problems auto-updating plugins and themes check on a WordPress site?
      • Will fixing problems auto-updating plugins and themes make my WordPress site safer in 2026?
      • Must-use plugins vs wp-config: where should an auto-update filter live to avoid problems auto-updating plugins and themes?
    TL;DR

    Your site may have problems auto-updating plugins and themes means one thing: code on your site is returning false from the auto_update_plugin or auto_update_theme filter for a made-up test plugin. It is not a cron fault, a permissions fault or a full disk. Critical means the dashboard still offers auto-updates that the filter overrides. Recommended means the filter and the dashboard agree that updates are off. Search your files for the filter, then reload Site Health.

    Problems Auto-Updating Plugins and Themes: What the Warning Actually Tests

    Site Health says Your site may have problems auto-updating plugins and themes, and the natural reaction is to hunt for a broken cron job, a permissions fault or a full disk. None of those is what this check looks at. The test never touches a file, never reads the cron schedule and never contacts WordPress.org. It asks a narrower question: has some code told WordPress to refuse plugin or theme updates while the dashboard still offers the switch? When the answer is yes, you get problems auto-updating plugins and themes in your Site Health list.

    Listen: the Site Health auto-update warning is a filter test against a made-up plugin, not a cron, permissions or disk fault. By Matt Chrust, Director of Business Development, AHosting.

    We read the source instead of the forum threads. This guide follows the WordPress 7.1.3 source tag, which we opened on October 14, 2026. The test is get_test_plugin_theme_auto_updates() at line 1815 of class-wp-site-health.php, and the warning label is set at line 1836. The actual decision is made further down in detect_plugin_theme_auto_update_issues(), which you can read on GitHub at lines 3192 to 3267. Core’s own comment on that function admits it is making educated guesses, because nobody can prove auto-updates are configured correctly from inside a request.

    The short answer: the warning means a filter named auto_update_plugin or auto_update_theme returned false for a made-up plugin, so the per-plugin switches on your Plugins screen are probably being overridden. Here is the whole test in one diagram.

    How Site Health grades plugin and theme auto-updates Two inputs feed one comparison. On the left, WordPress builds a fake plugin called a-fake-plugin and passes true through the auto_update_plugin filter, which gives the filter answer. Below it, WordPress asks whether the dashboard still shows auto-update switches, which gives the interface answer. On the right three outcomes follow. If the filter answer is false and the interface answer is on, the result is critical. If the filter answer is false and the interface is already off, the result is recommended. Otherwise the result is good. A filter test against a fake plugin WordPress 7.1.3, class-wp-site-health.php lines 3192 to 3267. No files, cron or network involved. 1. Filter answer auto_update_plugin( true, a-fake-plugin ) Same for the fake theme. Line 3223. 2. Interface answer Does the dashboard still show the auto-update switches? Line 3226. Critical Filter says false, switches still shown Recommended Filter says false, switches already hidden Good Filter says true, or nothing is hooked The real updater calls the same filter at class-wp-automatic-updater.php line 268.

    The Three Results of the Problems Auto-Updating Plugins and Themes Check

    The function can return only three statuses, and Site Health changes its label only when the status is not good. Good keeps the calm label that says auto-updates appear to be configured correctly. Critical and recommended both swap in the warning you are reading about, and the sentence under it is the only clue to which one you have.

    ResultCondition in the codeWhat the message saysLines
    CriticalThe filter returns false for the fake plugin or theme AND the dashboard still shows the switchesAuto-updates appear disabled, yet the settings are still displayed, which could stop them working3231 to 3238
    RecommendedThe filter returns false, a filter is hooked, and the dashboard switches are already hiddenAuto-updates for plugins, themes or both appear disabled, so new versions will not arrive on their own3240 to 3260
    GoodAnything else, including no filter at allThere appear to be no issues with plugin and theme auto-updates3263 to 3266
    AHosting Auto-Update Check Outcome Table: the three results of the WordPress 7.1.3 plugin and theme auto-update test, with the condition and line numbers in class-wp-site-health.php.

    Notice the order. Critical is tested first, so it wins whenever the dashboard and the filter disagree. Recommended is the quieter state: someone turned auto-updates off on purpose and made the screen match. The label is identical for both, which is why people assume the worst.

    Why Site Health Reports Problems Auto-Updating Plugins and Themes as Critical

    What the test sends through the filter

    WordPress builds a fake plugin with the slug a-fake-plugin and version 9.9, and a fake theme called a-fake-theme (lines 3194 to 3216). It then calls the same hook a real update would use, passing true as the starting answer (lines 3223 and 3224, through wp_is_auto_update_forced_for_item() at line 1085 of update.php). The hook is documented as the auto_update_{$type} filter. If nothing is hooked, true comes back unchanged and the result is good.

    Why the dashboard switch stops meaning anything

    The real updater starts from your own choice. The per-plugin switch is stored in a site option, read at line 227 of class-wp-automatic-updater.php, and the result is then passed through the same filter at line 268. Whatever the filter returns replaces your choice. A blanket false therefore turns every plugin switch into decoration: you can click Enable auto-updates on all of them and none will update.

    Filter patterns that trip the check, and ones that do not

    Because the test uses a fake slug, the shape of your filter decides the result. We worked these out from the source, and have not yet confirmed each one on a clean install.

    Filter patternAnswer for the fake pluginResult
    Return false for every pluginfalseTrips the check
    Allowlist: true only for named slugsfalse, because a-fake-plugin is not on the listTrips the check
    Denylist: false only for named slugstrue, because a-fake-plugin is not on the listPasses, even though real plugins are blocked
    Return true for every plugintruePasses
    No filter hooked anywheretrue, unchangedPasses
    How common auto_update_plugin filter shapes behave against the fake plugin used by the WordPress 7.1.3 Site Health test, derived from reading the source.

    The denylist row matters most. A green result does not prove your plugins update, because the check cannot see a filter aimed at specific slugs. The allowlist row is the surprise: a careful setup that updates only approved plugins looks identical to a blanket block.

    Finding the Code Behind Your Problems Auto-Updating Plugins and Themes Warning

    The filter is ordinary PHP that something on your site registers. You are looking for four strings: auto_update_plugin, auto_update_theme, plugins_auto_update_enabled and themes_auto_update_enabled. Search for them in this order, which runs from the most likely culprit to the least:

    1. The wp-content/mu-plugins folder. Must-use plugins load on every request and cannot be switched off from the Plugins screen, so a forgotten snippet can sit there for years.
    2. Active plugins. Anything that manages updates, maintenance mode, staging or client handover may register the filter. Search the plugin folders rather than guessing from names.
    3. The active theme’s functions.php and any child theme. Snippets pasted here vanish and reappear with theme changes.
    4. wp-config.php. It can hold add_filter lines as well as constants, and it is the file people forget to read.

    If you have terminal access, a recursive search for those strings finds them quickly. Without it, open each file in the order above and read it. Do the bisecting on a copy, not the live site: our WordPress staging guide covers setting one up, and renaming a plugin folder on production switches that plugin off for every visitor.

    If the search finds nothing, the filter may be registered from code that builds the hook name dynamically, or from a plugin that is only active for some users. In that case switch the suspects off one at a time on the staging copy and reload Site Health after each change. The plugin whose removal turns the warning to good is the one holding the filter.

    Constants that change what the dashboard shows

    Two constants affect the interface side of the test rather than the filter side. AUTOMATIC_UPDATER_DISABLED and DISALLOW_FILE_MODS both make the updater report itself as disabled (is_disabled(), lines 33 to 59 of the updater class, and wp_is_file_mod_allowed() at line 1829 of load.php). Both are documented on the wp-config reference. On their own they hide the switches and still leave the result good, because nothing has filtered the starting true. Together with a false filter they give you recommended.

    The hide-the-interface filters work the same way. The WordPress 5.5 developer note says returning false from plugins_auto_update_enabled or themes_auto_update_enabled only removes the interface, and does not turn auto-updates on or off. That is exactly why a site can end up critical: the filter blocks updates and nothing hides the switch.

    What the Problems Auto-Updating Plugins and Themes Check Cannot See

    Equally important is what this test ignores. It does not check that the server can write files, that cron fires, that the disk has room or that WordPress.org is reachable. Core runs a different item for those: Background updates, which is get_test_background_updates() at line 1740 and hands off to a separate class of tests. A site can pass this check and still fail to update, and fail this check while every other part of the update path is healthy.

    So match the symptom to the right guide. Should WordPress ask for FTP details when you click Update, read why it is a file-owner check, not a password problem. If updates are scheduled but never run, what the scheduled event check actually tests explains the cron side, and core’s own auto-update message at line 1096 of update.php blames WP-Cron when the update event is missing. When an install fails midway, finding the folder before the cause covers it.

    Why the filter matters for security

    The reason to care is the gap between a fix being published and installed. The US government publishes a catalog of vulnerabilities known to be exploited, the National Vulnerability Database records them, and WPScan lists WordPress plugin vulnerabilities specifically. A filter that silently blocks auto-updates removes the one mechanism that closes that gap without your attention, and the critical result is the one where nothing on screen tells you so.

    Fixing Problems Auto-Updating Plugins and Themes on AHosting

    The fix is a decision followed by a small change. Decide first whether you want auto-updates at all, because the answer sets which Site Health result is acceptable.

    1. You want auto-updates. Remove the filter that returns false, or replace a blanket false with a denylist of the few plugins you must pin. Reload Site Health: the result should return to good.
    2. You want an allowlist. The check cannot see through it, so you will get critical while the switches show. Hide them with plugins_auto_update_enabled and themes_auto_update_enabled and you will get recommended, which is accurate and honest.
    3. You want no auto-updates. Return false from the two interface filters as well, so the screen matches the code. The result becomes recommended, and you take on every update yourself.

    Whichever you pick, put the filter in a single must-use plugin file with a clear name, so the next person can find it. The same filters work identically on our AHosting shared web hosting and AHosting VPS hosting plans, because the filter lives in your WordPress files and not in the server. After the change, reload Site Health to confirm the result.

    Check the cron side separately. The Plugins screen has an auto-updates column, and the WordPress 5.5 developer note says it carries the toggle links and the time until the next update attempt. That time is built from the shared wp_version_check event (line 1096 of update.php), so it shows that cron is alive, not that your filter is clear. Site Health answers the filter question, and the column answers the cron question.

    Replay the result before you change anything

    The reader tool below runs the same two questions as core, so you can check which result you should expect before and after the change.

    Replay the Auto-Update Check

    Answer the two questions the test asks, and see which Site Health result core would print.

    Pick your answers, then replay the check.

    AHosting WordPress hosting plans

    When to open a ticket

    If you have searched every file above and the warning remains, open a ticket with the exact Site Health line and the list of must-use plugins in your account, and we will look at it with you.

    Frequently Asked Questions: Problems Auto-Updating Plugins and Themes

    Why won’t my WordPress plugins update in 2026 when Site Health reports problems auto-updating plugins and themes?

    Specifically, this warning does not explain a failed manual update. It says a filter named auto_update_plugin or auto_update_theme returned false for a made-up test plugin, so the per-plugin auto-update switches are probably being overridden. If a click on Update now also fails, that is a separate problem: check file ownership, disk quota and the Background updates item in Site Health.

    Is it safe to ignore the problems auto-updating plugins and themes warning if I update plugins by hand?

    In practice, yes for the moment, because the filter governs automatic updates, not the Update now button. The risk is the gap between releases: if you rely on auto-updates for a security fix and a filter blocks them, nothing installs until you notice. Either remove the filter or accept that you own every update.

    Does the problems auto-updating plugins and themes warning mean my cron or file permissions are broken?

    However, nothing in this test reads cron or permissions. It builds a fake plugin and theme, asks the auto_update filters what they would do, and compares that with whether the dashboard shows the toggles. Broken cron and wrong file ownership produce other Site Health items, not this one.

    Critical vs recommended in 2026: which problems auto-updating plugins and themes result is worse?

    Notably, critical is the contradictory one. It means a filter refuses updates while the dashboard still offers the switch, so the screen is lying to you. Recommended means the filter and the dashboard agree that updates are off, which is a deliberate state that only needs a decision.

    Can AHosting support help me find which plugin is behind the problems auto-updating plugins and themes warning?

    In practice, yes. Open a ticket with the exact Site Health line and the list of must-use plugins in your account, and we will look at it with you. The filter lives in your own files, so the quickest route is usually a search for auto_update_plugin across wp-content.

    On AHosting WordPress hosting, auto_update_plugin filter vs plugins_auto_update_enabled filter in 2026: which switches updates off?

    Specifically, the auto_update_plugin filter decides whether a given update runs, and returning false there blocks it. The plugins_auto_update_enabled filter only decides whether the dashboard shows the switches. Returning false from it hides the interface without turning anything on or off, which is why the two together can produce either Site Health result.

    How do I clear the problems auto-updating plugins and themes warning on an AHosting WordPress plan without editing core files?

    In other words, find the code that returns false and change that, never WordPress itself. Search mu-plugins, active plugins, the theme functions file and wp-config for auto_update_plugin and auto_update_theme, then remove the blanket false or narrow it to named plugins. Reload Site Health afterward to confirm.

    What does DISALLOW_FILE_MODS do to the problems auto-updating plugins and themes check on a WordPress site?

    Indeed, on its own it does not trigger this warning. The constant makes the updater report itself as disabled, which hides the dashboard switches, but the test still starts from true and nothing has filtered it, so the result stays good. Pair the constant with a filter that returns false and you get the recommended result instead.

    Will fixing problems auto-updating plugins and themes make my WordPress site safer in 2026?

    Consequently, only if the filter was blocking updates you wanted. Auto-updates close the gap between a plugin vulnerability being published and your site receiving the fixed version, but they do nothing about plugins that are abandoned or themes that no longer receive releases. Treat the fix as one control among several.

    Must-use plugins vs wp-config: where should an auto-update filter live to avoid problems auto-updating plugins and themes?

    For example, a must-use plugin is the safer home because it is a single named file that does not depend on the active theme, so you can find it again. Filters pasted into wp-config or a theme functions file get lost in upgrades, which is how they end up blocking updates years later.

    October 14, 2026
  • Available Disk Space Is Critically Low? What WordPress Is Really Measuring

    Available Disk Space Is Critically Low? What WordPress Is Really Measuring

    • What “Available Disk Space Is Critically Low” Actually Checks
      • One PHP Call Behind the Warning
      • The Heading That Never Changes
    • Why Available Disk Space Is Critically Low Ignores Your Quota
      • Green With a Full Account
    • “Could Not Determine Available Disk Space for Updates”
      • When a Disabled Function Reads as Critically Low
      • The Old Advice About wp-content/upgrade
    • Which Number to Trust When Available Disk Space Is Critically Low
      • Read Both Meters in cPanel
    • Check Available Disk Space Is Critically Low Yourself in Two Minutes
      • What the Value Means
      • Read Your Available Disk Space Is Critically Low Result
    • How to Fix Available Disk Space Is Critically Low, in Order
      • Where the Space Usually Goes
    • Available Disk Space Is Critically Low on AHosting Servers
      • What We Measured in October 2026
      • What the Plans Include
      • When to Open a Ticket
    • A Practical Checklist for Available Disk Space Is Critically Low
    • Frequently Asked Questions: Available Disk Space Is Critically Low
      • Why does WordPress say available disk space is critically low when I have enough?
      • What does available disk space is critically low mean in WordPress Site Health in 2026?
      • Critically low vs low vs could not determine: what is the difference in Site Health?
      • Does the available disk space is critically low warning read my hosting quota?
      • Can I safely ignore available disk space is critically low in Site Health?
      • Will creating a wp-content/upgrade folder fix the disk space warning in 2026?
      • Site Health vs cPanel Disk Usage: which disk space number should I trust?
      • How much disk space do AHosting WordPress hosting plans include in 2026?
      • Can AHosting support check an available disk space is critically low warning?
      • Does an AHosting VPS give an accurate Site Health disk space reading in 2026?
    TL;DR

    Available disk space is critically low means PHP reported under 20 MB free on the filesystem that holds wp-content. On shared hosting that filesystem belongs to the whole server, not to your plan, so the warning can be wrong in either direction. Read the Disk Usage meter in cPanel instead. Near its limit: clear old backups, logs and unused plugins before updating. Plenty of room: the warning is a measuring problem, not a full site.

    What “Available Disk Space Is Critically Low” Actually Checks

    Available disk space is critically low, less than 20 MB available. Proceed with caution, updates may fail. That is the full line WordPress Site Health prints, and it reads as if the site were about to run out of room. On shared hosting it often has nothing to do with your account. Read against the WordPress 7.1.3 code that writes it, the warning measures one thing, and that thing is not your hosting plan.

    Listen: the WordPress disk space warning reads the free space of the whole server, so on shared hosting it can be wrong in either direction. By Matt Chrust, Director of Business Development, AHosting.

    One PHP Call Behind the Warning

    The test has been part of Site Health since WordPress 6.3 and runs every time the screen loads. It calls PHP’s disk_free_space() on WP_CONTENT_DIR, the folder holding your plugins, themes and uploads, and sorts the answer into three bands. Under 20 MB is critical. Under 100 MB is low, graded recommended. Anything above that passes. If PHP returns no number at all, a fourth message appears instead, covered further down.

    The Heading That Never Changes

    One detail confuses almost everyone who meets this warning. In every state, including critical, the row in Site Health is titled Disk space available to safely perform updates. Only the text underneath changes. So a reassuring heading sits in the Critical issues list, and you have to expand it to read that available disk space is critically low. The badge beside it says Security.

    Why Available Disk Space Is Critically Low Ignores Your Quota

    PHP documents disk_free_space() as the bytes available on the corresponding filesystem or disk partition. Its source code asks the operating system through statvfs and multiplies the free blocks available to ordinary users, f_bavail, by the block size. That is a property of the disk, not of the customer asking.

    Shared hosting limits each customer a different way. As the Linux Quota mini-HOWTO explains, a quota caps the disk blocks and the number of files one user may own, per filesystem. Many accounts share one filesystem, each with its own ceiling. The free space of the filesystem and the room left under your ceiling are two separate numbers, and Site Health only reads the first.

    Site Health showsStatusWhat PHP returnedDoes it describe your account?Next step
    [Size] available disk space was detected, update routines can be performed safelyGoodFree space on the server filesystemNo, it can stay green with your quota fullCheck cPanel Disk Usage anyway
    Available disk space is low, less than 100 MB availableRecommendedUnder 100 MB free on the filesystemOnly if the filesystem is yours, as on a VPSCompare with Disk Usage
    Available disk space is critically low, less than 20 MB availableCriticalUnder 20 MB, or a non-number a host substitutedRarely on shared hostingCompare with Disk Usage; free space only if it is near the limit
    Could not determine available disk space for updatesRecommendedFalse: the function is disabled or failedNo number at allWatch Disk Usage before large updates
    What each disk space result in Site Health means — the exact message, its status, what disk_free_space() returned, and whether it describes your account, read from WordPress 7.1.3 and PHP source.

    Green With a Full Account

    The quiet failure is the green one. Your account can sit at its limit while the server filesystem has plenty left, and Site Health reports space detected. The next plugin update then fails with a refusal to create a folder or copy a file. WordPress does have a clearer message, Could not copy files. You may have run out of disk space, but it measures the same filesystem and only runs during scheduled background updates.

    Two meters, and Site Health reads the wrong one Two horizontal meters. The first is the server filesystem that holds every account, shown mostly empty, and an arrow labeled Site Health points to it: this is what PHP disk_free_space reports. The second is your account quota, shown nearly full, labeled cPanel Disk Usage: this is the limit a plugin or core update actually runs into. Beneath them, three outcomes: the filesystem has room but the quota is full, so Site Health shows green and the update still fails; the host disabled or replaced the PHP function, so Site Health shows critical or could not determine while both meters have room; and on a VPS the two meters are the same disk, so the reading is accurate. Two meters. Site Health reads only one. WordPress 7.1.3, Tools, Site Health, the disk space test on shared hosting. Server filesystem, shared by every account Site Health reads this Your account quota Updates hit this Green, update fails Server has room, your quota does not. Critical, plenty free Host replaced the PHP function. VPS: accurate One disk, one owner, one number. On shared hosting, cPanel Disk Usage is the meter that decides whether a file can be written.

    “Could Not Determine Available Disk Space for Updates”

    This is the same test reporting that PHP returned false. Some hosts add disk_free_space to their list of disabled PHP functions. WordPress then has no number and says so, graded recommended rather than critical. It is the honest version of the warning.

    When a Disabled Function Reads as Critically Low

    Trouble starts when a host replaces the function instead of disabling it. WordPress Trac ticket #59687 describes a managed host whose replacement returned null. WordPress only catches false, and in PHP null < 20 MB is true, so the test fell straight into the critical branch on sites with gigabytes free. Core developers closed it as a host issue. Ticket #59251, titled as Site Health incorrectly reporting low disk space, collected the same symptom from other sites before it was closed as fixed.

    The Old Advice About wp-content/upgrade

    Older forum threads tell you to create wp-content/upgrade. That worked once. WordPress 6.3.1 measured that folder, which a fresh install does not have yet, and a missing folder gave no number. In August 2024 a core commit pointed the test at WP_CONTENT_DIR itself, matching the unzip checks, and the change shipped in WordPress 6.7. Creating the folder today changes nothing.

    Which Number to Trust When Available Disk Space Is Critically Low

    Four places report disk space, and they answer four different questions. On shared hosting only one of them describes the limit your updates will run into.

    Where you read itWhat it measuresTrust it on shared hosting?On a VPS
    Site Health, Status tabFree space on the filesystem holding wp-contentNoYes
    cPanel Disk UsageSpace your account uses against its own quotaYes, this is the limitNot shown without cPanel
    cPanel File UsageFiles your account owns against its file-count limitYes, the second limitRarely limited
    Site Health, Info, Directories and SizesHow big WordPress folders areYes, for finding what grewYes
    df -h over SSHFree space on the filesystemNo, same as Site HealthYes
    quota -s over SSHYour usage and limitsYes, where the command is availableOnly if quotas are set
    Which number answers which question — every place a WordPress site owner can read disk space, what it measures, and whether it reflects a shared-hosting quota.

    Read Both Meters in cPanel

    The cPanel sidebar shows Disk Usage and File Usage side by side, and either one at its limit stops a write. A site can have gigabytes to spare and still be blocked because it owns too many small files, which our guide to the WordPress inode limit on shared hosting covers in detail. The quota command shows the same two limits from a terminal, where your host provides one.

    Check Available Disk Space Is Critically Low Yourself in Two Minutes

    Start with the cPanel meters. If Disk Usage shows plenty of room, the warning is a measuring problem, and you can stop here. If you want to see the number Site Health sees, a one-line test file shows it. Create a file with a random name, such as ds-check-4b9e.php, in the folder your domain serves, containing <?php var_dump(function_exists('disk_free_space') ? disk_free_space(__DIR__) : 'disabled');. Load it in a browser, note the value, and delete it straight away.

    What the Value Means

    • A large float: free bytes on the server filesystem. Divide by 1,048,576 for megabytes. If it dwarfs the room left in Disk Usage, you are reading the shared disk.
    • A float under 20,971,520: the filesystem really is under 20 MB. On shared hosting that is a server problem, not yours to solve.
    • bool(false) or the word disabled: the function is unavailable, which is why Site Health could not determine a number.
    • NULL: the host replaced the function. This is the false critical from ticket 59687.

    Read Your Available Disk Space Is Critically Low Result

    The same logic as a tool: enter the Site Health line and the cPanel meter, and it tells you whether the warning describes your account or the server, and the one step to take next.

    Disk Space Warning Reader

    Enter what Site Health and cPanel show. The answer is whether the warning describes your account or the server, which number to trust, and the one thing to do next.

    —

    What the warning describes:

    Number to trust:

    Do this next:

    Read from the WordPress 7.1.3 and PHP source. It cannot see your server, so cPanel Disk Usage is what settles it.

    How to Fix Available Disk Space Is Critically Low, in Order

    Work through these in sequence and stop at the first one that applies. Most shared-hosting sites stop at the first or second step.

    1. If cPanel Disk Usage shows plenty of room, leave the warning. Nothing you delete will change what PHP reports about a disk the whole server shares, and your updates have space.
    2. If Disk Usage is near its limit, free space before the next update. Old backup archives, leftover folders in wp-content/upgrade and wp-content/upgrade-temp-backup, cache folders, a grown debug.log, and plugins or themes you no longer use are the usual weight. Mailboxes on the same account count too.
    3. If Site Health says it could not determine the space, nothing is broken. WordPress just cannot pre-check for you, so glance at Disk Usage before a large update.
    4. If an update failed while Site Health was green, read both meters at once. A full quota and a full file count produce the same refusal.
    5. If both meters show room and the warning still says critical, the measurement is the host’s. Ask, and send the exact Site Health line with the Disk Usage figure.

    Where the Space Usually Goes

    A failed install leaves its download behind, and our guide to installation failed: could not create directory shows what a full quota does to the next one. Temporary files count as well: PHP’s own temporary folder can sit inside your account, as our post on the missing a temporary folder error explains. And a debug log left switched on grows without limit, which is one more reason to follow our advice on logging errors to a potentially public file.

    Available Disk Space Is Critically Low on AHosting Servers

    On our shared servers, customer home folders sit on a filesystem that enforces a separate quota for every cPanel account, and each account’s PHP temporary folder lives inside that same quota. So the rule in this guide applies directly: Site Health reads the shared filesystem, and the Disk Usage meter in your cPanel is the number that decides whether a plugin, theme or core update can be written.

    What We Measured in October 2026

    We ran the same PHP call as a customer account on one of our shared servers in October 2026. It returned about 2,385 GB, the free space of the shared filesystem, while that account had 4.73 GB left of its 5 GB quota. Against thresholds of 20 MB and 100 MB, the test therefore reports good for every account on that server, including one with no room left at all. The function is not disabled on any PHP version we offer, so the could-not-determine message does not appear either. In twelve months of support tickets, no customer has reported this warning to us. We send our own high disk usage notices instead, because the per-account number is the one that matters and WordPress cannot see it.

    What the Plans Include

    Our WordPress hosting plans include 10 GB, 20 GB and 50 GB of storage, and the standard web hosting plans carry the same three figures. A routine update needs only a fraction of that, but it needs the space at the moment it runs: the download and its unpacked copy exist side by side until the copy finishes. Keeping Disk Usage comfortably below its limit is what makes updates boring.

    When to Open a Ticket

    Clearing space is the fix in most cases, and it is yours to make. If cPanel shows room to spare and Site Health still says critically low, open a ticket with the exact Site Health line and the Disk Usage figure, and we will look at it with you. If you would rather the Site Health number be your number, a VPS with full root access puts the whole disk in your hands. The warning alone is not a reason to move.

    A Practical Checklist for Available Disk Space Is Critically Low

    • Expand the Site Health row; the heading reads the same in every state.
    • Read cPanel Disk Usage before deleting anything.
    • Read File Usage too; a file-count limit blocks writes just as a full disk does.
    • Treat a critical warning with plenty of room in Disk Usage as a measuring problem.
    • Ignore advice to create wp-content/upgrade; it stopped mattering in WordPress 6.7.
    • Clear old backups, leftover upgrade folders, caches and logs when Disk Usage is near its limit.
    • Keep room for the download and its unpacked copy before a large update.
    • Delete any test file as soon as you have its value.
    • Send the Site Health line and the Disk Usage figure with any question to your host.

    Frequently Asked Questions: Available Disk Space Is Critically Low

    Why does WordPress say available disk space is critically low when I have enough?

    Typically because the number is not about your account. Site Health asks PHP how much space is free on the filesystem that holds wp-content, and PHP has no idea what your plan allows. A critical result with room to spare usually means the host replaced that PHP function with one that returns no number, or the shared server disk itself is nearly full. Check the Disk Usage meter in cPanel: if it shows room, nothing on your site needs deleting.

    What does available disk space is critically low mean in WordPress Site Health in 2026?

    In other words, PHP reported less than 20 MB free where WordPress keeps plugins, themes and uploads. WordPress 7.1 runs the check every time Site Health loads and grades it critical under the Security badge, because an update needs room to download, unpack and copy files. Between 20 MB and 100 MB the same test says low instead, graded recommended.

    Critically low vs low vs could not determine: what is the difference in Site Health?

    Specifically, all three come from one test. Critically low means PHP returned under 20 MB and is graded critical. Low means under 100 MB and is graded recommended. Could not determine means PHP returned no number at all, usually because the host disabled the function, and is also graded recommended. The heading above all three reads the same, so expand it to see which one you have.

    Does the available disk space is critically low warning read my hosting quota?

    In fact, no. PHP asks the operating system for the free space of the whole filesystem, and a hosting quota is a separate per-account limit kept on top of it. On a shared server the two numbers can be gigabytes apart in either direction. Your quota is the Disk Usage figure in cPanel, and that is the one your updates actually run into.

    Can I safely ignore available disk space is critically low in Site Health?

    Above all, make one check first. If cPanel Disk Usage shows plenty of room, the warning is a measuring problem and your updates will have space, so it is safe to leave. If Disk Usage is close to its limit, the warning is right for the wrong reason, and the next plugin or core update may fail halfway. Free space first, then update.

    Will creating a wp-content/upgrade folder fix the disk space warning in 2026?

    Ultimately, no. WordPress 6.3.1 measured the upgrade folder, which a fresh install does not have yet, so creating it changed the result. Since WordPress 6.7 the test measures wp-content itself, so the folder makes no difference in 2026. Old forum threads that recommend it describe a version you are no longer running.

    Site Health vs cPanel Disk Usage: which disk space number should I trust?

    In practice, trust cPanel on shared hosting. Disk Usage shows what your account has used against its own limit, which is what decides whether a file can be written. Site Health shows the free space of a disk the whole server shares. On a VPS the two describe the same disk, so either one will do.

    How much disk space do AHosting WordPress hosting plans include in 2026?

    Overall, as published on the plan pages in October 2026, the three WordPress plans include 10 GB, 20 GB and 50 GB of storage, and the standard web hosting plans carry the same three figures. Your own limit and how much of it is used appear in the Disk Usage meter in cPanel, which is the number to watch before a large update.

    Can AHosting support check an available disk space is critically low warning?

    Notably, on our shared servers the test reads a filesystem with terabytes free, so it reports good even for a full account, which is why Disk Usage is the meter to watch. If cPanel shows room to spare and Site Health still says critically low, open a ticket with the exact Site Health line and the Disk Usage figure, and we will look at it with you.

    Does an AHosting VPS give an accurate Site Health disk space reading in 2026?

    Fortunately yes, because on a VPS the filesystem belongs to your server alone, so the free space PHP reports is the free space you have. A warning there is real and worth acting on: clear old backups and logs first. A VPS is not needed just to clear this warning on a shared plan, though.

    October 9, 2026
  • Opcode Cache Is Not Enabled? What WordPress 7 Actually Checks

    Opcode Cache Is Not Enabled? What WordPress 7 Actually Checks

    • What “Opcode Cache Is Not Enabled” Actually Checks
      • What an Opcode Cache Does
      • One Function Call Behind Opcode Cache Is Not Enabled
    • Three Causes of Opcode Cache Is Not Enabled, and Only Two Mean It Is Off
      • The Shared Hosting False Alarm
    • “Disabled by Configuration”: Reading the Info Tab
      • Why the Memory and Hit-Rate Rows Disappear
    • Why .user.ini Cannot Fix Opcode Cache Is Not Enabled
      • The Line That Can Switch Opcode Cache Off
    • Check Opcode Cache Is Not Enabled Yourself in Two Minutes
      • What the Three Values Mean
      • Why SSH and WP-CLI Say Opcode Cache Is Not Enabled
      • Decode Your Opcode Cache Is Not Enabled Result
    • How to Fix Opcode Cache Is Not Enabled, in Order
      • Opcode Cache Is Not Enabled Is Not the Other Cache Warnings
    • Opcode Cache Is Not Enabled on AHosting Servers
      • Where OPcache Sits Next to LiteSpeed Cache
      • When to Open a Ticket
    • A Practical Checklist for Opcode Cache Is Not Enabled
    • Frequently Asked Questions: Opcode Cache Is Not Enabled
      • How do I fix WordPress OPcache not enabled in PHP?
      • What does opcode cache is not enabled mean in WordPress Site Health in 2026?
      • Opcode cache is not enabled vs Disabled by configuration: what is the difference?
      • Why does Site Health say opcode cache is not enabled when phpinfo shows OPcache running?
      • Can I fix opcode cache is not enabled with .user.ini on shared hosting?
      • Is it safe to hide the opcode cache is not enabled test in Site Health?
      • PHP 8.4 vs PHP 8.5: does PHP 8.5 turn on OPcache automatically in 2026?
      • How do I check opcode cache is not enabled on AHosting shared hosting in 2026?
      • Can AHosting support check why my site says opcode cache is not enabled?
      • Do I need an AHosting VPS to control OPcache settings in 2026?
    TL;DR

    Opcode cache is not enabled means one PHP function, opcache_get_status, did not confirm that OPcache is on. That happens when the cache really is off, and also when it is running but your host restricts the function. Open Site Health, Info, Server first. Disabled by configuration usually means the cache works and there is nothing to fix. Disabled means it is off, and only a PHP version change or your host can turn it on, because PHP refuses to switch it on from .user.ini.

    What “Opcode Cache Is Not Enabled” Actually Checks

    Opcode cache is not enabled is the Site Health warning many site owners first met after updating to WordPress 7.0, on a server nobody had touched. It reads as if the host had switched off a performance feature. Read against the WordPress 7.1.3 code that writes it, the message is narrower than that: one PHP function did not confirm that the cache is on, and the reason is not always that it is off.

    Listen: the warning comes from one PHP function call, and on shared hosting it often fires while OPcache is still running. By Matt Chrust, Director of Business Development, AHosting.

    What an Opcode Cache Does

    PHP does not run your theme and plugin files as written. It first compiles each file into opcodes, the small instructions its virtual machine executes; Nikita Popov’s walkthrough of the PHP 7 virtual machine shows what they look like. OPcache keeps those compiled opcodes in shared memory, so a file is compiled once and reused on later requests instead of being compiled again on every page load. A WordPress page touches hundreds of PHP files, which is why PHP’s own developers describe running a production site without OPcache as a mistake.

    One Function Call Behind Opcode Cache Is Not Enabled

    The test, listed in Site Health as Opcode cache, arrived in WordPress 7.0 and runs each time the Site Health screen loads. It calls opcache_get_status() and passes only when that function returns a report whose opcache_enabled value is true. Any other answer gives opcode cache is not enabled, graded recommended under the Performance badge. Nothing on the site breaks. When the cache really is off, PHP files are simply compiled again on every request.

    Three Causes of Opcode Cache Is Not Enabled, and Only Two Mean It Is Off

    The status function can fail to confirm the cache in three different ways, and WordPress treats all three the same. Two of them mean the cache is genuinely off. The third is the one shared-hosting customers keep reporting, and in that case the cache is working normally.

    • Extension not loaded. On PHP 8.4 and older, OPcache is an optional extension. If the PHP version your site runs does not load it, the status function does not exist at all.
    • Switched off. OPcache is loaded, but opcache.enable is off, either for the whole server or for your site. Here the function does answer, and its answer says the cache is off.
    • API restricted. Your host sets opcache.restrict_api to a folder outside your account, so that one customer cannot read or reset the shared cache. PHP then refuses the call with a warning and returns false, while the cache keeps serving every page.

    The Shared Hosting False Alarm

    The third case is WordPress Trac ticket #65395, titled as a false report of opcode cache is not enabled on shared hosting. Reporters on two different hosts posted phpinfo output showing OPcache up and running beside the warning. A patch proposes falling back to the opcache.enable setting when the status function is blocked. It is still awaiting review, and in WordPress 7.1.3 the check is unchanged. WordPress already knows about the restriction elsewhere: its own routine for clearing the cache after an update checks it before calling the API. The new Site Health test does not.

    One warning, three Info values At the top, the Site Health warning Opcode cache is not enabled. Below it, three branches for the Opcode cache row under Info, Server. Enabled, with memory and hit-rate rows beneath it: the cache is running and the warning should not appear. Disabled: either the OPcache extension is not loaded or the opcache.enable switch is off, so the cache is off and a PHP version change or the host can turn it on. Disabled by configuration: the status function returned false, which on shared hosting usually means the host restricts the OPcache API while the cache keeps running, and less often that OPcache failed to start. A footer notes that a .user.ini file can switch OPcache off but never on. One warning. Three Info values. One real fault. WordPress 7.1.3, Tools, Site Health, Info, Server, the Opcode cache row. Opcode cache is not enabled Enabled Memory and hit-rate rows appear below it. Cache running. No warning to fix. Disabled Extension not loaded, or switched off. Cache off. A PHP version change or your host turns it on. Disabled by configuration The status function returned no answer. Usually: API restricted, cache running. Rarely: failed to start. A .user.ini line can switch OPcache off for your site. PHP refuses to switch it on from there.

    “Disabled by Configuration”: Reading the Info Tab

    The Status tab shows the same label for every cause. The Info tab does not. Open Tools, Site Health, Info, expand Server, and find the Opcode cache row. WordPress fills it from the same function, but it reports how the function failed, which is what separates the false alarm from a real fault.

    Opcode cache row in InfoWhat the status function returnedIs OPcache caching your site?Who can change it
    Enabled, with memory and hit-rate rows below itA report saying the cache is onYesNothing to change
    DisabledNothing: the function does not exist because the extension is not loadedNoA PHP version change, or the host
    DisabledA report saying the cache is offNoYour .user.ini if it switches it off, otherwise the host
    Disabled by configurationFalse, because the host restricts the APIYesThe host only; a WordPress fix is pending
    Disabled by configurationFalse, because OPcache failed to startNoThe host only
    What the Opcode cache row in Site Health Info means — each value, what the status function returned, and whether OPcache is really running, read from WordPress 7.1.3 and PHP source.

    Why the Memory and Hit-Rate Rows Disappear

    When the cache reports itself enabled, WordPress adds rows for memory usage, interned strings usage, hit rate and whether the cache is full. When the status function is restricted, those numbers are exactly what the host chose to keep private, so the rows vanish and only Disabled by configuration remains. A missing hit-rate row is therefore not evidence that the cache is idle. It means WordPress was not allowed to ask.

    Why .user.ini Cannot Fix Opcode Cache Is Not Enabled

    The most common advice for this warning is a block of OPcache settings pasted into .user.ini or the cPanel MultiPHP INI Editor, starting with opcache.enable=1. PHP itself refuses most of it. The OPcache runtime configuration page says the switch can only be disabled at runtime, never enabled, and PHP’s source is blunter still: a true value is accepted only while PHP starts. A per-folder file is read later than that, so the line fails with a warning that OPcache cannot be temporarily enabled.

    OPcache settingWhere PHP accepts itFrom .user.ini on shared hostingOn a VPS
    opcache.enableAnywhere, but only to switch off after startupOff only, never onYes, in the PHP-wide ini
    opcache.restrict_apiSystem level onlyIgnoredYes
    opcache.enable_cliSystem level onlyIgnoredYes
    opcache.memory_consumptionSystem level onlyIgnoredYes
    opcache.interned_strings_bufferSystem level onlyIgnoredYes
    opcache.max_accelerated_filesSystem level onlyIgnoredYes
    opcache.validate_timestampsAnywhereYesYes
    opcache.revalidate_freqAnywhereYesYes
    Which OPcache settings you can change, and where — read from the OPcache module source for PHP 8.4.

    The Line That Can Switch Opcode Cache Off

    The same rule cuts the other way. A .user.ini line setting opcache.enable to 0 is accepted, and it switches the cache off for every request in that folder, so check for it before assuming the server is at fault. Our post on why a WordPress memory limit change does not take covers which PHP settings files are actually read, and the same files are the place to look here.

    Check Opcode Cache Is Not Enabled Yourself in Two Minutes

    The Info tab narrows it down. A three-value test file settles it, because it reads the switch directly instead of asking the status function. Create a file with a random name, such as oc-check-7f3a.php, in the folder your domain serves, containing one line: <?php var_dump(extension_loaded('Zend OPcache'), ini_get('opcache.enable'), ini_get('opcache.restrict_api'));. Load it in a browser, note the three values, and delete it straight away.

    What the Three Values Mean

    • true, 1, then a path: OPcache is loaded and on, and the path is the restriction. This is the false alarm. The cache is working.
    • true, 1, then an empty string: loaded, on and unrestricted, yet Site Health still warns. The cache most likely failed to start, which only the host can see.
    • true, then 0 or an empty string: loaded but switched off. Look for a line that switches it off before asking anyone.
    • false, false, false: the extension is not loaded for this PHP version.

    Why SSH and WP-CLI Say Opcode Cache Is Not Enabled

    Do not run this check over SSH. PHP on the command line has its own setting, opcache.enable_cli, which is off by default, and without it OPcache does not start in the command-line PHP at all. A check run there reports the cache as off whatever the website is doing. Tideways’ guide to tuning OPcache makes the same point: every kind of PHP process has its own shared memory, so the console cannot see the web server’s cache. Load the test file through the domain.

    Decode Your Opcode Cache Is Not Enabled Result

    The same logic as a tool: enter the Info row and the test-file values, and it tells you whether the cache is really off and the one step to take next.

    Opcode Cache Warning Decoder

    Enter what Site Health and the test file show. The answer is whether OPcache is really off, why WordPress says so, and the one thing to do next.

    —

    Is OPcache caching your site?

    Why WordPress warns:

    Do this next:

    Read from the WordPress 7.1.3 and PHP source. It cannot see your server, so the test file is what settles it.

    How to Fix Opcode Cache Is Not Enabled, in Order

    Work through these in sequence and stop at the first one that applies. Most shared-hosting sites stop at the first step.

    1. If the Info row says Disabled by configuration and the test file shows 1 and a path, the cache is running. Leave it. Nothing you change in WordPress will alter the result, and the warning costs nothing.
    2. If you want the warning gone anyway, remove only this test with the site_status_tests filter, unsetting the opcode_cache entry from the direct list in a small must-use plugin. Remove it again when WordPress fixes the check.
    3. If the test file shows the switch off, search .user.ini in your site folder and the cPanel MultiPHP INI Editor for opcache.enable set to 0, remove it, wait five minutes for PHP to reread the file, and check again.
    4. If the extension is not loaded, open cPanel MultiPHP Manager, try another PHP version on a staging copy first, then run the test file again. PHP 8.5 always loads OPcache.
    5. If none of that changes the Info row, the setting lives at server level. Ask your host, and send the Info row and the three test values with the question.

    Opcode Cache Is Not Enabled Is Not the Other Cache Warnings

    Site Health has two more Performance warnings about caching, and fixing this one does not touch them. OPcache keeps compiled code. A page cache keeps finished pages, covered in our guide to the page cache is not detected warning, and a persistent object cache keeps database results between requests, covered in you should use a persistent object cache. Each is a separate setting with its own warning.

    Opcode Cache Is Not Enabled on AHosting Servers

    On our shared servers, PHP runs as your own cPanel user through LiteSpeed, one of the server interfaces OPcache supports, and the Zend OPcache extension is present on all three of our shared servers; the test file shows whether the PHP version you picked loads it. That has two practical consequences for this warning. The test file, loaded through your domain, sees exactly the PHP your site uses, so its three values are the answer for your account. And .user.ini in your site folder is read, so a stray line switching the cache off would take effect here and is worth checking for.

    Where OPcache Sits Next to LiteSpeed Cache

    OPcache speeds up the PHP that runs. A page served from LiteSpeed’s page cache runs no PHP at all, so the two stack rather than compete: the page cache handles repeat visitors, and OPcache handles everything it cannot serve, such as logged-in sessions, carts and the admin area. Our comparison of server-side and plugin fixes for TTFB shows where each layer sits in a request.

    When to Open a Ticket

    Everything in this guide works the same way on our WordPress hosting plans and standard web hosting plans. If the Info tab says Disabled and switching PHP versions does not change it, open a ticket with that row and the PHP version you run, and we will look at it with you. If you want to choose the cache size or the restriction yourself, a VPS with full root access puts the PHP-wide settings in your hands. The warning alone is not a reason to move.

    A Practical Checklist for Opcode Cache Is Not Enabled

    • Read the Opcode cache row under Site Health, Info, Server before changing anything.
    • Treat Disabled by configuration as a likely false alarm until a test says otherwise.
    • Load the three-value test file through the domain, never over SSH.
    • Delete the test file as soon as you have the three values.
    • Look for opcache.enable set to 0 in .user.ini and remove it.
    • Never paste OPcache memory settings into .user.ini; PHP ignores them there.
    • Try another PHP version on a staging copy before switching the live site.
    • Hide the test only after confirming the cache runs, and only in a must-use plugin.
    • Fix page caching and object caching separately; this warning covers neither.
    • Send the Info row and the three test values with any question to your host.

    Frequently Asked Questions: Opcode Cache Is Not Enabled

    How do I fix WordPress OPcache not enabled in PHP?

    First and foremost, find out whether OPcache is really off. Open Tools, Site Health, Info, Server and read the Opcode cache row. Disabled by configuration usually means OPcache is running and your host restricts its status function, so there is nothing to fix. Disabled means it is off: try another PHP version in cPanel MultiPHP Manager, remove any line that switches it off, or ask your host.

    What does opcode cache is not enabled mean in WordPress Site Health in 2026?

    In other words, one PHP function did not confirm that the cache is on. WordPress 7.0 added the test, and in 7.1 it passes only when opcache_get_status returns a report saying OPcache is enabled. Any other answer, including no answer at all, gives the warning. It is graded recommended under the Performance badge, so your site keeps working either way.

    Opcode cache is not enabled vs Disabled by configuration: what is the difference?

    Specifically, the first is the Status label and the second is one of the values Site Health shows for the Opcode cache row on its Info tab. The Status label appears for every cause. The Info value narrows it down: Disabled means the cache is off, while Disabled by configuration means the status function refused to answer, which on shared hosting usually means the cache is running.

    Why does Site Health say opcode cache is not enabled when phpinfo shows OPcache running?

    Typically because your host restricts which scripts may call the OPcache status function. PHP then returns false with a warning, and WordPress reads false as off. The cache keeps working for every page. WordPress Trac ticket 65395 reports exactly this on shared hosting, and a proposed patch would fall back to the opcache.enable setting, but it is not part of WordPress 7.1.3.

    Can I fix opcode cache is not enabled with .user.ini on shared hosting?

    In fact, no. PHP accepts opcache.enable set to 1 only when PHP starts, so the same line in .user.ini is refused with a warning. The memory and file-count settings often suggested alongside it are system-level and ignored there too. What .user.ini can do is switch OPcache off for your site, so check that yours does not contain opcache.enable set to 0.

    Is it safe to hide the opcode cache is not enabled test in Site Health?

    Indeed it is, once you have confirmed that OPcache is running. Removing the test with the site_status_tests filter changes only what Site Health reports, not how PHP behaves. Do it in a small must-use plugin rather than a theme, and remove it again when WordPress ships a fix, because a hidden test cannot warn you if the cache is ever switched off for real.

    PHP 8.4 vs PHP 8.5: does PHP 8.5 turn on OPcache automatically in 2026?

    In practice, only partly. On PHP 8.4 and older, OPcache is an extension a host may or may not load. On PHP 8.5 it is built into PHP and always loaded, but the opcache.enable switch is still honored, so a host can still switch it off, and a restricted status function still gives the same false warning. Check the Info tab after switching versions.

    How do I check opcode cache is not enabled on AHosting shared hosting in 2026?

    Above all, check through the website, not over SSH. Read the Opcode cache row in Site Health Info, then load the three-value test file from this guide in a browser and delete it afterward. On our servers PHP runs as your own cPanel user through LiteSpeed, which OPcache supports, so the test file sees exactly what your site sees.

    Can AHosting support check why my site says opcode cache is not enabled?

    Notably, a Disabled by configuration result with opcache.enable on needs no ticket, because the cache is working. If the Info tab says Disabled and switching PHP versions in MultiPHP Manager does not change it, open a ticket with that row and the PHP version you run, and we will look at it with you.

    Do I need an AHosting VPS to control OPcache settings in 2026?

    Fortunately not to clear this warning. On a shared plan the cache size, the status-function restriction and the master switch are set for the whole server. A VPS makes sense when you want to choose those yourself, for example to give a large WooCommerce store more OPcache memory or to watch hit rates in Site Health.

    October 8, 2026
  • Log Errors to a Potentially Public File? What Site Health Checks

    Log Errors to a Potentially Public File? What Site Health Checks

    • What “Log Errors to a Potentially Public File” Actually Means
      • Three Settings Checked, and No Look at the File
      • Critical or Recommended: Which Badge You Get
    • Why Moving debug.log Does Not Clear the Potentially Public File Warning
      • The Grade Follows a Path Prefix
      • A Protected Log Still Reads as Critical
      • Recommended Does Not Mean Private
    • Display Errors to Site Visitors vs a Potentially Public File
      • Why WP_DEBUG_DISPLAY Hides the Potentially Public File Label
      • The Development Environment Exception
    • Is Your Potentially Public File Actually Public? Test It
      • What a 200, 403 or 404 Means
      • What a WordPress Debug Log Gives Away
    • How to Fix a Potentially Public File Warning, in Order
      • Grade Your Potentially Public File Setup
    • Potentially Public File Warnings on AHosting Servers
      • Where to Put debug.log on AHosting
      • A Log Left Running Never Stops Growing
    • A Practical Checklist for the Potentially Public File Warning
    • Frequently Asked Questions: Log Errors to a Potentially Public File
      • Why does Site Health still say potentially public file after I moved debug.log?
      • What does log errors to a potentially public file mean in WordPress in 2026?
      • Potentially public file vs display errors to site visitors: which warning is worse?
      • Can a potentially public file protected by htaccess still show as critical?
      • Does turning off WP_DEBUG delete the potentially public file in wp-content?
      • WP_DEBUG_LOG true vs a custom path: which one is safer on a live site?
      • How do I set a custom debug log path in WordPress 7.1 in 2026?
      • Where should I put debug.log on AHosting shared hosting in 2026?
      • Can AHosting support help me read the log behind a potentially public file warning?
      • Do I need an AHosting VPS to debug WordPress with errors displayed in 2026?
    TL;DR

    Your site is set to log errors to a potentially public file means two settings in wp-config.php, WP_DEBUG and WP_DEBUG_LOG, are both on while error display is off. Site Health never checked whether the log can be downloaded. The grade depends only on whether the log’s path sits inside your WordPress folder, so moving the file lowers the warning to recommended but never clears it. Read what you need, turn WP_DEBUG off, then delete the old debug.log, because turning logging off does not remove the file.

    What “Log Errors to a Potentially Public File” Actually Means

    Your site is set to log errors to a potentially public file is the Site Health warning that can turn up long after a fix, once nobody remembers switching debugging on. It sounds as if WordPress found your error log on the open web. Read against the WordPress 7.1.2 code that writes it, the message is much narrower: Site Health has not found the file, and it has not tried to.

    Listen: Site Health reads two settings and a path, never the log itself, so only switching debugging off turns it green. By Matt Chrust, Director of Business Development, AHosting.

    Three Settings Checked, and No Look at the File

    The test behind the warning, listed in Site Health as Debugging enabled, reads three constants from wp-config.php. When WP_DEBUG and WP_DEBUG_LOG are both on, and WP_DEBUG_DISPLAY is off, the label reads log errors to a potentially public file. The test does not open the log, does not check that it exists and does not request it over the web. Its own description calls the file potentially available to all users, and potentially is the operative word.

    Set to true, WP_DEBUG_LOG sends every PHP error, warning and notice to debug.log in the content folder, usually wp-content/debug.log. As the WordPress debugging handbook explains, you can instead give it a full file path to have the log saved elsewhere. That one option is the whole difference between the two grades the warning can carry.

    Critical or Recommended: Which Badge You Get

    Site Health files the warning under its Security badge, and it can carry either grade. It is critical when the log path starts with the WordPress folder, the path WordPress calls ABSPATH, and recommended when it starts anywhere else. The default wp-content/debug.log sits inside that folder, so most sites see it as a critical issue. Neither grade means anything is broken. The site keeps working; the warning is about who else might be able to read your errors.

    Why Moving debug.log Does Not Clear the Potentially Public File Warning

    The most common surprise is that moving the log changes nothing visible. One reporter on the WordPress bug tracker put it plainly: setting the log path to a system folder should fix it, but does not. The code explains why. This is the full grading, read from the test in the current release.

    Settings in wp-config.phpLabel Site Health showsGrade
    WP_DEBUG false or not set (anything else ignored)Not set to output debug informationGood
    WP_DEBUG true, WP_DEBUG_LOG false, display offNot set to output debug informationGood
    WP_DEBUG true, WP_DEBUG_DISPLAY true or not setDisplay errors to site visitorsCritical (recommended in development)
    WP_DEBUG true, WP_DEBUG_LOG true, display offLog errors to a potentially public fileCritical
    WP_DEBUG true, WP_DEBUG_LOG a path inside the WordPress folder, display offLog errors to a potentially public fileCritical
    WP_DEBUG true, WP_DEBUG_LOG a path outside the WordPress folder, display offLog errors to a potentially public fileRecommended
    What WordPress 7.1 Site Health reports for each debug setting — label and grade, read from the core Debugging enabled test.
    The potentially public file grade follows the path, not the exposure A folder tree starting at the account home folder. Inside it, public_html is the folder the domain serves. WordPress is installed in public_html/blog, which is ABSPATH. The default log at public_html/blog/wp-content/debug.log is inside ABSPATH and graded critical, and a visitor can download it unless a rule blocks it. A log at public_html/logs/debug.log is outside ABSPATH and graded recommended, yet a visitor can still download it. A log at home/wp-logs/debug.log is outside ABSPATH and outside public_html, graded recommended, and no address points to it. Only turning WP_DEBUG off turns the result green. The grade follows the path, not the exposure. WordPress 7.1.2, WP_DEBUG and WP_DEBUG_LOG on, display off. WordPress installed in /blog. /home/user/ public_html/ served by the domain blog/ (ABSPATH) wp-content/debug.log critical, downloadable unless a rule blocks it logs/debug.log recommended, and still downloadable wp-logs/debug.log recommended, and no address points to it What Site Health reads Does the log path start with ABSPATH? Yes: critical No: recommended It never requests the file over the web. Green only with WP_DEBUG off. If WordPress sits directly in public_html, public_html/logs starts with ABSPATH too, and is graded critical.

    The Grade Follows a Path Prefix

    The test compares the start of PHP’s error log setting with ABSPATH, and nothing more. A log outside the WordPress folder is graded recommended, but the label stays, because the label depends only on the two constants being on. So no log location turns the result green. The only green is WP_DEBUG off. Ticket #64071 on WordPress Trac asks for the test to treat a log outside the WordPress folder as safe. It is still open and marked for a future release, so in 7.1.2 the label remains.

    A Protected Log Still Reads as Critical

    The reverse also holds. A log in wp-content protected by a deny rule, so that a request for it returns an error, still starts with the WordPress folder and is still graded critical. The rule really does protect the file. Site Health simply has no way of knowing it is there, because it never sends a request to find out.

    Recommended Does Not Mean Private

    The prefix test can also err the other way. Say WordPress is installed in public_html/blog/ and the log is moved to public_html/logs/. That path does not start with the WordPress folder, so Site Health grades it recommended, yet the folder is still inside public_html, and the web server will deliver the file to anyone who asks for it. The grade measures a path. Whether the file can be downloaded is something you have to test.

    Display Errors to Site Visitors vs a Potentially Public File

    The same test has a second label, Your site is set to display errors to site visitors, and it is the worse of the two. It means errors are printed into the pages every visitor loads, rather than written to a file someone would have to know to request. Site Health grades it critical.

    Why WP_DEBUG_DISPLAY Hides the Potentially Public File Label

    WordPress defines WP_DEBUG_DISPLAY as true unless you set it yourself, and the code reference for wp_debug_mode() confirms that WordPress then forces errors to be displayed. When the display setting is true, the test overwrites the log label with the display label. So a site that turns on WP_DEBUG and WP_DEBUG_LOG and stops there sees display errors to site visitors, not the log warning. You only meet log errors to a potentially public file after display has been turned off, which makes it the warning of someone who followed the careful recipe. Setting display to null also counts as off here, because WordPress then leaves the server’s own display setting alone, so check that the server is not displaying errors itself.

    The Development Environment Exception

    One setting changes the display grade. When WP_ENVIRONMENT_TYPE is set to development or local, Site Health lowers the display warning to recommended, because printing errors on a development copy is expected. The log warning gets no such exception: its grade depends only on the path. Never set either environment type on a live site to quiet the warning, since plugins read the same value and may change how they behave.

    Is Your Potentially Public File Actually Public? Test It

    Because Site Health never checks, the only way to know is to ask for the file the way a stranger would. Open a private browser window, so no login cookie is sent, and request your domain followed by /wp-content/debug.log. From a terminal, curl -I with the same address prints only the response status. If you set a custom path inside public_html, request the address that matches it instead.

    What a 200, 403 or 404 Means

    • 200: the file is public. Anyone who requests that address can download it, and so can any automated tool that requests the default path.
    • 403: a rule refuses the request. The file is protected at that address, whatever Site Health says.
    • 404: there is no file at that address right now. Either nothing has been logged yet or the log lives elsewhere. A log created later at the same path would be served, so a 404 is not a reason to leave logging on.

    What a WordPress Debug Log Gives Away

    A debug log is written for whoever is fixing the site, so it holds what an attacker would otherwise have to work out. Each PHP warning carries the full server path to the file that raised it, which on shared hosting includes your account username, along with plugin and theme folder names. WordPress also logs failed database queries in full, prefixed with WordPress database error, table names included. MITRE’s description of gathering software information about a target lists accessible data sets as one way that information reaches an attacker. The UK National Cyber Security Centre’s introduction to logging for security purposes asks whether access to logs is limited to the people who need to analyze them. A log in a public folder fails that test by default.

    How to Fix a Potentially Public File Warning, in Order

    Work through these in sequence. The first two steps clear the warning, and the third closes the exposure that the warning was about.

    1. Save what you need. Download debug.log through cPanel File Manager before you change anything, and read it on your own machine.
    2. Turn debugging off. Set WP_DEBUG to false in wp-config.php. That one change stops WordPress writing the log and turns the result green; the other two constants do nothing while it is off.
    3. Delete the old log. Turning logging off does not remove the file, and it stays downloadable until you delete it. Request its address again afterward and expect a 404.
    4. If you need logging for days, move it. Create a folder outside public_html, then set WP_DEBUG_LOG to the full path of a file inside it. PHP creates the file, not the folder.
    5. If the log must stay in wp-content, deny it. Add a rule to the .htaccess file in that folder: a Files block naming debug.log that contains Require all denied. Then request it again and expect a 403. The badge stays critical.
    6. Next time, start with the server’s log. Our guide to the WordPress white screen of death shows where cPanel lists recent PHP errors, which often names the failing file without turning WordPress logging on at all.

    Grade Your Potentially Public File Setup

    The same logic as a tool: enter the settings from your wp-config.php and it returns the label and grade Site Health will show, whether the log can be downloaded, and the next step.

    Potentially Public File Grader

    Copy the debug settings from your wp-config.php. The answer is the label and grade Site Health will show, whether a visitor can actually download the log, and what to do next.

    —

    Grade:

    Can a visitor download it?

    Do this next:

    Read from the WordPress 7.1.2 source. It cannot see your server, so confirm the download answer by requesting the file yourself.

    Potentially Public File Warnings on AHosting Servers

    On our shared servers, PHP runs as your own cPanel user, inside CloudLinux CageFS. Our post on server-level WordPress security explains what that isolation does. For a debug log it means two things. WordPress can write to any folder in your home folder without a permissions change, and a folder outside public_html has no address on the web. Your home folder is /home/ followed by your cPanel username, so a path such as /home/username/wp-logs/debug.log is the one to use. Avoid folders that serve another domain on the account.

    Where to Put debug.log on AHosting

    The handbook’s own example path is /tmp. That works here, but inside CageFS your /tmp is a private folder in your own account that counts against both your disk and inode quota, and a named folder is easier to find later.

    Where the log livesSite Health gradeCan a visitor download it?Verdict
    wp-content/debug.log (WP_DEBUG_LOG true)CriticalYes, unless a rule blocks itOnly while you are reading it
    wp-content/debug.log with a deny ruleCriticalNo, if a test returns 403Acceptable for a short session
    Elsewhere in public_htmlCritical or recommended, by where WordPress is installedYesNever
    /tmp (the handbook example)RecommendedNoWorks; counts against disk and inode quota
    /home/username/wp-logs/debug.logRecommendedNoBest place for a log you need for days
    Logging off (WP_DEBUG false)GoodOnly an old file, until you delete itThe only green result
    Where to put debug.log on AHosting — each location’s Site Health grade, whether a visitor can download it, and our verdict.

    A Log Left Running Never Stops Growing

    WordPress never rotates or trims debug.log. Every warning and notice adds a line, so a log left running grows against your disk quota and adds a steady stream of small writes; our guide to disk I/O throttling on shared hosting covers why those add up. That is a second reason to treat logging as a session with an end, not a setting.

    Everything in this guide works the same way on our WordPress hosting plans and standard web hosting plans. If the log keeps filling with the same error and you cannot tell which plugin writes it, open a ticket with the first lines of the log and we will look at it with you. For a separate staging copy where errors can be displayed safely, a VPS with full root access lets you set the PHP logging setup for the whole server yourself. The warning alone is not a reason to move.

    A Practical Checklist for the Potentially Public File Warning

    • Note which label Site Health shows: the log warning or the display warning.
    • Request /wp-content/debug.log in a private window and note the status.
    • Download the log before changing anything if you still need it.
    • Set WP_DEBUG to false as soon as the debugging is finished.
    • Delete the old debug.log, then request it again and expect a 404.
    • For logging over several days, use a full path outside public_html.
    • Create the folder first, because PHP creates the log file but not its folder.
    • Never leave WP_DEBUG_DISPLAY on for a live site.
    • Treat a recommended grade as a path check, not proof that the file is private.
    • Check the cPanel error log first next time, before switching WordPress logging on.

    Frequently Asked Questions: Log Errors to a Potentially Public File

    Why does Site Health still say potentially public file after I moved debug.log?

    In practice, the check never looks at the file. Site Health shows the label whenever WP_DEBUG and WP_DEBUG_LOG are both on. Moving the log out of the WordPress folder only changes the grade from critical to recommended, because the grade depends on whether the path starts with the WordPress folder. The label clears only when logging is off, so turn WP_DEBUG off once you have what you need.

    What does log errors to a potentially public file mean in WordPress in 2026?

    In other words, WP_DEBUG and WP_DEBUG_LOG are both set to true in wp-config.php while error display is off. In WordPress 7.1 Site Health reads those settings and nothing else. It does not check whether the log exists or whether a visitor can download it. The warning is critical when the log sits inside the WordPress folder and recommended when it sits anywhere else.

    Potentially public file vs display errors to site visitors: which warning is worse?

    Specifically, display errors to site visitors is worse, because every visitor sees the errors in the page itself. Both labels come from the same test. WP_DEBUG_DISPLAY defaults to true, so a site that turns on WP_DEBUG without turning display off gets the display label, graded critical. The potentially public file label only appears once display is off, and it describes a file someone has to request by its address, which is the same default address on every site.

    Can a potentially public file protected by htaccess still show as critical?

    Indeed it can. Site Health grades the log by its path alone, and a log in wp-content starts with the WordPress folder, so it is graded critical whether or not a rule blocks it. A deny rule that returns 403 does protect the file. It does not change the grade, and only turning logging off or moving the log changes what Site Health reports.

    Does turning off WP_DEBUG delete the potentially public file in wp-content?

    In fact, no. Setting WP_DEBUG to false stops WordPress from writing new entries and turns the Site Health result green, but the debug.log already on disk stays where it is, and the web server keeps serving it. Download it if you still need it, then delete it in File Manager. Request its address once more afterwards; a 404 confirms that it is gone.

    WP_DEBUG_LOG true vs a custom path: which one is safer on a live site?

    Typically a custom path outside the folder your domain serves. Set to true, WP_DEBUG_LOG writes to wp-content/debug.log, which the web server can deliver to anyone who requests it. Set to a full path in your home folder, it writes somewhere no address points to, and Site Health lowers the grade to recommended. Logging still writes on every error, so turn it off when you are done.

    How do I set a custom debug log path in WordPress 7.1 in 2026?

    First and foremost, create the folder, because PHP creates the log file but not the folder that holds it. Then set WP_DEBUG_LOG to the full path in wp-config.php, above the line that says to stop editing, for example /home/ followed by your cPanel username and /wp-logs/debug.log. Trigger a page load, confirm the file appears, and check that Site Health now grades the warning as recommended.

    Where should I put debug.log on AHosting shared hosting in 2026?

    Above all, outside public_html, in a folder of its own in your home folder. On our servers PHP runs as your own cPanel user inside CageFS, so WordPress can write to a folder there with no permission changes, and no address on the web points to it. Avoid other folders a domain on the account serves from, and turn logging off when the debugging is finished.

    Can AHosting support help me read the log behind a potentially public file warning?

    Notably, the warning itself needs no ticket: turning WP_DEBUG off clears it, and deleting the old file closes the exposure. If the log keeps filling with the same error and you cannot tell which plugin writes it, open a ticket with the first lines of the log and we will look at it with you.

    Do I need an AHosting VPS to debug WordPress with errors displayed in 2026?

    Fortunately not for this warning. Logging to a file outside public_html works on a shared plan and keeps errors away from visitors. A VPS makes sense when you want a separate staging copy where errors can be displayed safely, with the environment type set to development, or when you want to choose the PHP logging setup for the whole server yourself.

    October 7, 2026
  • A Scheduled Event Has Failed? What Site Health Actually Checked

    A Scheduled Event Has Failed? What Site Health Actually Checked

    • What “A Scheduled Event Has Failed” Actually Means
      • A Clock Comparison, Not a Failure Report
      • Why Site Health Files It Under Recommended
    • A Scheduled Event Has Failed vs Is Late: Two Windows
      • Why DISABLE_WP_CRON Widens the Windows
      • Is Late Can Be Your Own Page Load
    • Why the Event It Names Is Rarely the One That Broke
      • It Names the Oldest Event Still Waiting
      • Each Event Leaves the List Before It Runs
      • A Dead Run Holds the Lock for a Minute
      • See the Whole Queue, Not One Name
    • Four Reasons a Scheduled Event Has Failed
      • Every Visit Was Answered From Cache
      • The Loopback That Starts Cron Fails
      • DISABLE_WP_CRON Is Set and No Server Cron Runs
      • A Run Died Partway Through
    • “A Scheduled Event Is Late”: When to Ignore It
    • How to Fix a Scheduled Event Has Failed, in Order
      • Decode Why a Scheduled Event Has Failed
    • A Scheduled Event Has Failed on AHosting Servers
    • A Practical Checklist When a Scheduled Event Has Failed
    • Frequently Asked Questions: A Scheduled Event Has Failed
      • Why are my scheduled WordPress posts not being published on time?
      • What does a scheduled event has failed mean in WordPress Site Health in 2026?
      • A scheduled event has failed vs is late: what is the difference in Site Health?
      • Which event does Site Health name when a scheduled event has failed?
      • Why does a scheduled event has failed appear on a well cached WordPress site?
      • DISABLE_WP_CRON vs server cron: which one stops a scheduled event has failed?
      • How do I list every overdue cron event in WordPress 7.1 in 2026?
      • Does AHosting run WP-Cron for my WordPress site automatically in 2026?
      • Can AHosting support help when the scheduled event has failed warning keeps returning?
      • Do I need an AHosting VPS for reliable WordPress cron jobs in 2026?
    TL;DR

    A scheduled event has failed does not mean the event it names tried to run and failed. Site Health compared each waiting event’s due time with the clock and found one more than five minutes overdue, or more than an hour if DISABLE_WP_CRON is set. The event it names is the oldest one still waiting, and often not the one that broke. Reload once after a minute, then find out why nothing ran wp-cron.php in time: visits answered entirely from cache, a broken loopback, WP-Cron disabled with no server cron, or a run that died partway.

    What “A Scheduled Event Has Failed” Actually Means

    A scheduled event has failed is the Site Health warning that reads like a crash report: The scheduled event, wp_version_check, failed to run. Read against the WordPress 7.1.2 code that writes it, the warning reports neither a crash nor an attempt to run. Site Health looked at the list of scheduled events, compared each due time with the current time, and found one that should have run more than five minutes ago.

    Listen: Site Health compares due times with the clock, names the oldest waiting event, and a quiet, well-cached site can starve WP-Cron. By Matt Chrust, Director of Business Development, AHosting.

    A Clock Comparison, Not a Failure Report

    WordPress keeps its scheduled events, also called cron events, in a single list in the database, each one stamped with the time it is due. When you open Tools, Site Health, the scheduled-events test reads that list fresh. It consults no log of past runs, and it stores nothing about late events between visits. If any due time is more than five minutes in the past, the label becomes A scheduled event has failed. The word failed describes a missed deadline, not an error that anything caught.

    Why Site Health Files It Under Recommended

    Site Health grades the warning as recommended, not critical, and the message itself says your site still works. That grade is accurate. Core features ride on this list, as the WordPress Plugin Handbook chapter on cron explains: checking for updates and publishing scheduled posts both depend on it. A stalled list delays those jobs; it does not take the site down. The only critical result this test can return is a different message, It was not possible to check your scheduled events, which appears when the list is empty.

    A Scheduled Event Has Failed vs Is Late: Two Windows

    The same test has a milder label, A scheduled event is late, and one constant in wp-config.php moves both thresholds. This is the full grading, read from the test in the current release. Both warnings are graded recommended.

    How overdue the oldest waiting event isDISABLE_WP_CRON not setDISABLE_WP_CRON set to true
    Not due yetPassesPasses
    Up to 5 minutesA scheduled event is latePasses
    5 to 15 minutesA scheduled event has failedPasses
    15 to 60 minutesA scheduled event has failedA scheduled event is late
    More than 60 minutesA scheduled event has failedA scheduled event has failed
    How WordPress 7.1 Site Health grades scheduled events — by how far past due the oldest waiting event is, read from the core test.
    How Site Health decides that a scheduled event has failed A horizontal timeline with a vertical line marking now. To the right of now, an event that is not due yet passes the test. In the five minutes before now is the is late window, containing one event. Everything earlier than five minutes before now is the has failed window, containing two events. The leftmost, oldest event carries a highlight ring and the label named in the warning. A note explains that a hook which crashed the last run was removed from the list before it ran, so it does not appear on the timeline at all. A second note says that with DISABLE_WP_CRON set the windows become 15 to 60 minutes for late and more than an hour for failed. Site Health compares due times with the clock. WordPress 7.1.2, default thresholds. Nothing on this line tried to run and failed. A scheduled event has failed more than 5 minutes past due is late 0 to 5 min not due yet passes the test now named in the warning also overdue The oldest waiting event is the one Site Health names. A hook that crashed the last run left the list before it ran, so it is not on this line at all. With DISABLE_WP_CRON set: late means 15 to 60 minutes past due, failed means more than an hour.

    Why DISABLE_WP_CRON Widens the Windows

    Setting DISABLE_WP_CRON tells WordPress that something other than page loads runs the list, normally a server cron on a fixed interval. Site Health allows for the gap between those runs: 15 minutes before an event counts as late, and an hour before it counts as failed. Our own server-cron walkthrough uses a 15-minute interval for a standard site, which matches that allowance. Setting the constant with no server cron behind it is the one change guaranteed to produce this warning, just an hour later.

    Is Late Can Be Your Own Page Load

    Since WordPress 6.9, a page load starts the cron run at the very end of the request rather than near the start. The WordPress 6.9 performance field guide explains why: the old position could add up to a second to the time to first byte. One side effect matters here. When you open Site Health just as an event comes due, the test runs first and the cron run starts after it, so the screen can report a late event that your own visit is about to clear. Wait a minute and reload before you diagnose anything.

    Why the Event It Names Is Rarely the One That Broke

    The message names one event, and it is natural to blame the plugin that owns it. The code that runs the list says the name is a weaker clue than it looks.

    It Names the Oldest Event Still Waiting

    WordPress keeps the list in order of due time, and the test stops at the first event that crosses the threshold. So the name you see belongs to the most overdue event still in the list. On a site where nothing has run for hours, that is simply whichever job came due first, a core check such as wp_version_check just as easily as a plugin hook. It tells you the list stopped moving. It does not tell you why.

    Each Event Leaves the List Before It Runs

    When wp-cron.php works through the list, it handles due events in time order, inside one PHP process. For each one it first books the next occurrence if the event repeats, then removes the current entry, and only then runs the code attached to it. If that code ends the process with a fatal error, the event that caused it has already left the list. Everything queued behind it stays overdue, and Site Health names one of those. The event that broke the run is the one you will not see.

    A Dead Run Holds the Lock for a Minute

    Each run sets a lock when it starts and clears it when it finishes. A run that dies never clears its lock, and WordPress refuses to start another for 60 seconds, the default value of WP_CRON_LOCK_TIMEOUT. After that minute, the next qualifying visit starts a fresh run, which reaches the broken hook again only when that hook is next due. That is how a crashing job can produce a warning that comes and goes rather than one that never clears.

    See the Whole Queue, Not One Name

    To see every overdue event at once, use the WP-CLI command wp cron event list. It prints now for every event whose time has passed, however late, so add the next_run_gmt field to see how late each one really is. Without a shell, the free WP Crontrol plugin shows the same list in the dashboard. Two snapshots a few minutes apart tell you more than any single warning: an unchanged list means nothing ran, and a list that shrank but kept one plugin’s hooks overdue points at the code queued just ahead of them.

    Four Reasons a Scheduled Event Has Failed

    Every version of this warning comes down to one of two facts: nothing ran wp-cron.php in time, or something ran it and the run died. Four causes account for those, and each one leaves a different trace.

    Every Visit Was Answered From Cache

    WP-Cron has no clock of its own. The handbook is plain about it: WP-Cron is only triggered on page load. Each request that reaches WordPress checks the list and, if something is due, starts a run. A request answered by a full-page cache is served before WordPress gets as far as checking the list, and with a server-level cache such as LiteSpeed, PHP never starts at all. On a quiet site with a good cache, nearly every visit can be a cache hit, and a long stretch can pass without a single request that reaches the cron check. Our guide to LiteSpeed Cache and Cloudflare covers the two layers that can answer visits before WordPress does.

    This is the cause the usual advice gets backwards. Clearing the cache makes the warning disappear for a while, because the next visits are built by WordPress again, and that is easy to mistake for a fix. Logging in to look usually has the same effect, since logged-in visits are normally not served from the page cache.

    The Loopback That Starts Cron Fails

    A page load does not run the jobs itself. It sends a short request from the site to its own wp-cron.php, waits a hundredth of a second, and moves on. If that request cannot reach the site, because a firewall or security rule blocks it, a password prompt guards the whole site, or the domain resolves somewhere else from the server, no run ever starts and nothing reports an error. Site Health tests the same route separately, and our guide to Your site could not complete a loopback request decodes that result.

    DISABLE_WP_CRON Is Set and No Server Cron Runs

    With DISABLE_WP_CRON set, page loads stop starting runs altogether. The constant is meant to be paired with a server cron, and a cron daemon works on the clock, not on visits: the cron(8) manual describes it waking up every minute to check what is due, and the Rocky Linux guide to cron jobs notes that tasks start on the daemon’s own notion of time. If that job was never added, was lost in a migration or points at the wrong folder, nothing runs the list, and after an hour the warning appears. Our walkthrough on when to disable WP-Cron covers the pairing step by step.

    A Run Died Partway Through

    A run can also start and not finish. A plugin hook can end it with a fatal error, a PHP time limit can stop it, or a process limit on the account can end it. The traces are the ones described above: the named event can change from one check to the next, and the PHP error log has an entry from the minute the run died that names the plugin file responsible. On shared hosting, our resource limit diagnostic tree shows how to tell an account limit from a code fault.

    “A Scheduled Event Is Late”: When to Ignore It

    The late label means the oldest waiting event is no more than five minutes overdue, or 15 to 60 minutes overdue when DISABLE_WP_CRON is set. On its own it can simply mean a run was about to start, or started a moment after the test.

    A variant that comes up in searches is The scheduled event, action_scheduler_run_queue, is late to run. That hook belongs to Action Scheduler, the job queue that WooCommerce and many other plugins ship with. Its documentation says the queue runner is triggered by WP-Cron at most once a minute, so a hook due every minute is the first to look late whenever the gap between runs grows. It is a sensitive gauge, not a separate fault.

    Ignore a late warning that clears on reload. Act on one that is still there after several reloads a few minutes apart, or one that turns into the failed label, because both mean the list is not moving.

    How to Fix a Scheduled Event Has Failed, in Order

    Work through these in sequence. Each step either clears the warning or narrows the cause, and the order puts the cheapest checks first.

    1. Wait a minute and reload Site Health. If the warning has gone, your own page load cleared it.
    2. Load your site’s wp-cron.php once by hand: your domain followed by /wp-cron.php. A blank page is the normal result, and the run continues after the page comes back. Wait a minute, then reload Site Health.
    3. If the warning cleared, the list can run and the trigger is the problem. Check the loopback test, look in wp-config.php for DISABLE_WP_CRON, and consider how much of your traffic is answered from cache.
    4. If a different event is named now, a hook is ending the run. Open the PHP error log in cPanel and read the entries from that minute. The plugin file named there is where to start.
    5. If nothing changed, the run did not start. Wait 60 seconds for the lock, try again, and check that no security rule refuses requests to wp-cron.php.
    6. For a quiet, well-cached site, stop depending on visits and run the list from a server cron, as our guide to WordPress cron jobs on shared hosting describes.

    Decode Why a Scheduled Event Has Failed

    The same steps as a lookup table, from the result you see to the cause and the first fix.

    What you seeMost likely causeFirst fix
    Late, and it clears on reloadYour own page load started the runNothing to fix
    Failed, and it clears after loading wp-cron.php by handNothing triggered a run in timeFind the missing trigger: cache, loopback or the constant
    Failed on a quiet site with a page cacheVisits never reach the cron checkAdd a server cron in cPanel
    Failed, and the loopback test fails tooThe run request never arrivesFix the loopback first
    Failed, and DISABLE_WP_CRON is setThe server cron is missing or brokenCheck Cron Jobs in cPanel
    A different event named after each runA hook is ending the runRead the PHP error log from that minute
    Nothing changes after a manual runThe run did not startWait out the lock, then check security rules
    The AHosting Scheduled Event Decoder — what Site Health and a manual run show, the likely cause, and the first fix.

    Scheduled Event Has Failed Decoder

    Five questions about the warning and what happened when you tested it. The answer names the most likely reason the list stopped moving and the next thing to do.

    —

    Most likely:

    Do this next:

    Read from the WordPress 7.1.2 source. It cannot see your server, so treat the answer as where to start, not as a diagnosis.

    A Scheduled Event Has Failed on AHosting Servers

    Our shared servers run LiteSpeed, and LiteSpeed answers a cached page itself: on our servers a cached page consumes no entry processes, because no PHP process is started for it. That is good for speed and for staying inside a plan’s limits, and it is also why a quiet, well-cached site here can go a long stretch without running WP-Cron. In our July 2026 audit of one shared server, all 26 WordPress installs still used the default WP-Cron, and none of their 676 scheduled events was overdue. Sites with ordinary traffic kept their lists moving; the warning points at a quiet site, a broken trigger or a crashing hook.

    We do not add a server cron to accounts by default. Cron Jobs in cPanel is available on our WordPress hosting plans and standard web hosting plans, and PHP runs as your own cPanel user, so a cron job runs WordPress with exactly the access the site already has. If wp-cron.php runs, the list drains and the warning still comes back, open a ticket with the event name Site Health shows and we will look at it with you.

    Sites with heavy scheduled work, such as a large WooCommerce queue, can outgrow what a shared account allows. A VPS with full root access lets you set the cron schedule, the PHP time limits and the process counts yourself. One warning is not a reason to move; a queue that never catches up might be.

    A Practical Checklist When a Scheduled Event Has Failed

    • Note the exact label, failed or late, and the event name it shows.
    • Wait a minute and reload Site Health before changing anything.
    • Load wp-cron.php once by hand, wait a minute, and reload again.
    • Compare the full list of overdue events before and after, not just the one name.
    • Check the loopback test result on the same Site Health screen.
    • Look in wp-config.php for DISABLE_WP_CRON, and in cPanel for a matching cron job.
    • Read the PHP error log for entries from the minute a run died.
    • On a quiet, well-cached site, move the list to a server cron rather than clearing the cache.
    • Never set DISABLE_WP_CRON until the server cron is confirmed to run.
    • Contact your host only when the list runs by hand, drains, and the warning still returns.

    Frequently Asked Questions: A Scheduled Event Has Failed

    Why are my scheduled WordPress posts not being published on time?

    Typically because nothing ran WordPress cron when the post came due. Scheduled posts are published by a cron event, and WordPress only starts cron from a visit that is not answered by a page cache. On a quiet site, or one whose visits are all answered by a page cache, the publish time can pass with no such visit, and Site Health then reports that a scheduled event has failed. A server cron, or regular uncached visits with a working loopback, fixes it.

    What does a scheduled event has failed mean in WordPress Site Health in 2026?

    In other words, an event in the cron list is more than five minutes past its due time. In WordPress 7.1 Site Health compares each due time with the clock when you open the screen. It keeps no record of failed runs, and the warning does not mean the named event tried to run. With DISABLE_WP_CRON set, the threshold is one hour instead. The warning is graded recommended, and the site keeps working.

    A scheduled event has failed vs is late: what is the difference in Site Health?

    In practice it is only the size of the delay. Is late means the oldest waiting event is up to five minutes overdue, and has failed means more than five minutes. With DISABLE_WP_CRON set, late covers 15 to 60 minutes and failed covers anything past an hour. A late warning that clears when you reload a minute later can simply be your own page load starting the run.

    Which event does Site Health name when a scheduled event has failed?

    Specifically, the oldest event still waiting in the list. The list is kept in order of due time and the test stops at the first event past the threshold. Because WordPress removes each event from the list just before running it, a hook that crashes the run has already left the list, so the named event can be one queued behind the real cause. Read the PHP error log from the minute the run died.

    Why does a scheduled event has failed appear on a well cached WordPress site?

    Notably, a page answered by a full-page cache is served before WordPress reaches the step that starts cron. On a quiet site where nearly every visit is a cache hit, a long stretch can pass without a request that runs the cron list. Logging in to check can clear the warning, because logged-in visits are normally not served from the page cache, which hides the cause. A server cron removes the dependence on visits.

    DISABLE_WP_CRON vs server cron: which one stops a scheduled event has failed?

    Together, and never the constant alone. DISABLE_WP_CRON only stops page loads from starting runs and widens the Site Health threshold to one hour. Without a server cron running the list on a schedule, nothing runs it at all, and the warning returns once that hour has passed. Add the cron job in cPanel first, confirm that it runs, and only then set the constant in wp-config.php.

    How do I list every overdue cron event in WordPress 7.1 in 2026?

    First and foremost, use WP-CLI, where wp cron event list shows every scheduled event with its hook and due time. WP-CLI prints now for every event that is already due, however late, so add the next_run_gmt field to see how late each one is. Without a shell, the free WP Crontrol plugin shows the same list inside the dashboard. Two snapshots a few minutes apart show whether the list is moving.

    Does AHosting run WP-Cron for my WordPress site automatically in 2026?

    Indeed, WordPress runs its own WP-Cron on our servers exactly as it does anywhere, started by visits that are not answered from a page cache. We do not add a server cron to accounts by default, so a quiet or heavily cached site depends on those visits. Cron Jobs in cPanel is available on our WordPress and web hosting plans, and PHP runs as your own user, so you can add one without a ticket.

    Can AHosting support help when the scheduled event has failed warning keeps returning?

    Above all, run the checks in this guide first: reload after a minute, load wp-cron.php by hand, check the loopback test and look for DISABLE_WP_CRON. Each one rules out a cause. If wp-cron.php runs, the list drains and the warning still comes back, open a ticket with the event name Site Health shows and we will look at it with you.

    Do I need an AHosting VPS for reliable WordPress cron jobs in 2026?

    Fortunately not for this warning alone. Every cause in this guide, from cache-only traffic to a missing server cron or a crashing hook, is fixed inside a shared account. A VPS makes sense when scheduled work, such as a large WooCommerce queue, keeps outgrowing the limits of a shared plan, or when you want to set PHP time limits and process counts yourself.

    October 6, 2026
  • Installation Failed: Could Not Create Directory? Find the Folder, Then the Cause

    Installation Failed: Could Not Create Directory? Find the Folder, Then the Cause

    • What “Installation Failed: Could Not Create Directory” Means
      • The Sentence Leaves Out the Two Things You Need
      • Why WordPress Cannot Tell You the Reason
    • Where Could Not Create Directory Comes From: Five Places, One Sentence
      • Unpacking Into wp-content/upgrade
      • Moving Into wp-content/plugins or themes
    • Get the Path WordPress Hid From You
      • Upload the Plugin Zip Instead
      • Turn On WP_DEBUG and Read the Browser Console
      • What the Folder in the Path Tells You
    • Why a Full Account Says Could Not Create Directory
      • The Disk-Space Check Only Runs in the Background
      • Folders Are Created Before Any File
      • What the Server Actually Said
      • Read Both Meters in cPanel
    • When Could Not Create Directory Really Is Permissions
      • The Modes WordPress Expects
      • Why chmod 777 Is the Wrong Fix
      • Ownership After a Migration or Restore
    • “Could Not Create the upgrade-temp-backup Directory” on Updates
    • How to Fix Could Not Create Directory, in Order
    • Could Not Create Directory on AHosting Servers
    • A Practical Checklist for Could Not Create Directory
    • Frequently Asked Questions: Could Not Create Directory
      • What does Installation failed: Could not create directory mean in WordPress?
      • Which folder does WordPress fail to create when a plugin install fails in 2026?
      • Could not create directory vs Could not copy file: what is the difference in WordPress?
      • Disk space vs inode limit: which one causes could not create directory on shared hosting?
      • Why does could not create directory appear when cPanel shows free disk space?
      • Is chmod 777 on wp-content a safe fix for could not create directory?
      • How do I see the full error path in WordPress 7.1 in 2026?
      • Does AHosting shared hosting let WordPress create plugin folders directly in 2026?
      • Can AHosting support fix could not create directory on my WordPress site?
      • Do I need an AHosting VPS to stop WordPress plugin install errors in 2026?
    TL;DR

    Installation failed: Could not create directory means the server refused a new folder, and WordPress hides both which folder and why. Get the path first: the Upload Plugin screen prints it. Then read Disk Usage and File Usage in cPanel, because on a host where PHP runs as your own user the account limits come before the permissions, and WordPress reports a full account as this exact message. Folders belong at 755. Never use 777.

    What “Installation Failed: Could Not Create Directory” Means

    Installation failed: Could not create directory is the line WordPress prints on the plugin card when an install stops partway, and the usual advice is to loosen permissions until it goes away. Read against the code that produces it, that advice skips two steps. The sentence means PHP asked the server for a new folder and the server said no. It does not say which folder, and it does not say why, and both of those decide the fix.

    Listen: the same sentence comes from five places in WordPress, a full account prints it too, and chmod 777 fixes none of them. By Matt Chrust, Director of Business Development, AHosting.

    The Sentence Leaves Out the Two Things You Need

    A plugin or theme install creates folders at two separate moments: when the zip is unpacked into a working area, and when the result is put in its final place. A refusal at either moment produces the same words. The reason is just as hidden. A folder can be refused because PHP may not write to the parent, because the account has no disk space left, or because it has no file slots left, and the message is identical in all three cases.

    Why WordPress Cannot Tell You the Reason

    When PHP fails to make a folder, the PHP manual for mkdir() says it emits a warning describing the problem. WordPress calls it with the warning suppressed and keeps only a yes or no answer. The operating system did report a reason, and that reason is discarded before the message is written. So treat Could not create directory as a symptom with several causes, and narrow it down in the order below rather than guessing.

    Where Could Not Create Directory Comes From: Five Places, One Sentence

    In WordPress 7.1.2, the current release, the identical sentence is produced in five places in the install and update code. Each one is a different step, each one knows the exact folder it failed on, and each one attaches that folder to the error as its path.

    StepFolder being createdError codeWhat it usually means
    Unpacking with ZipArchivewp-content/upgrade/ plus every folder inside the zipmkdir_failed_ziparchiveNo room, no free inodes, or wp-content/upgrade is not writable
    Unpacking with the fallback unzipperThe same folders, when ZipArchive is not availablemkdir_failed_pclzipThe same causes as above
    Creating the destinationwp-content/plugins/slug/ or the theme foldermkdir_failed_destinationThe plugins or themes folder is not writable, or the account filled up
    Moving into placeThe destination, when a direct move failsmkdir_failed_move_dirThe same causes as the destination step
    Copying a subfolderA folder inside the destinationmkdir_failed_copy_dirThe account ran out of room partway through
    Where “Could not create directory” comes from in WordPress 7.1.2 — five steps, one sentence, read from the core install code.
    Where could not create directory happens during a WordPress plugin install Step one downloads the plugin zip to the temporary folder. Step two unpacks it into a working folder under wp-content/upgrade, creating every folder in the package before writing any file. Step three moves the result into wp-content/plugins under the plugin slug. Steps two and three each create folders, and either failure prints Could not create directory. WordPress attaches the folder path to the error. The Install Now button on the plugin card drops the path and shows only the sentence. The Upload Plugin screen prints the sentence followed by the path. A refused folder can mean no write permission, no disk space left in the quota, or no inodes left in the quota, and the message does not say which. Two steps create folders. Both print the same sentence. A plugin install in WordPress 7.1.2, and where “Could not create directory” comes from. 1. Download zip saved to the temp folder no folders created here 2. Unpack wp-content/upgrade/… all folders first, then files 3. Install wp-content/plugins/slug/ move, or create and copy Could not create directory. + the folder path Install Now button shows the sentence, drops the path Upload Plugin screen shows the sentence and the path No permission, no space and no free inodes all print the same line. The path is where you start.

    Unpacking Into wp-content/upgrade

    The unpack step creates the most folders, so it has the most chances to fail. The unzip_file() reference describes the function WordPress uses: it extracts the package into a working folder under wp-content/upgrade. WordPress empties that folder at the start of each install by itself, so leftovers from an earlier failure are not the problem and do not need clearing by hand.

    Moving Into wp-content/plugins or themes

    Once the package is unpacked, WordPress moves it into its final folder under the plugin or theme slug. A failure here, after a clean unpack, points at the destination folder specifically: wp-content/plugins or wp-content/themes no longer accepts new folders, or the account filled up between the two steps.

    Get the Path WordPress Hid From You

    The path is already in the error. The Install Now button on a plugin card simply does not show it: the card prints Installation failed: followed by the message alone. Two screens print the rest, and either one turns a guess into a specific folder.

    Upload the Plugin Zip Instead

    Download the plugin zip from its page in the plugin directory, then go to Plugins, Add New, Upload Plugin and install the file. That screen uses the older step-by-step output. It prints Unpacking the package or Installing the plugin, then the error followed by the full folder path, then Plugin installation failed. The step printed just before the error tells you which of the two moments failed.

    Turn On WP_DEBUG and Read the Browser Console

    If you would rather keep using the button, set WP_DEBUG to true in wp-config.php. With it on, the install reply carries a list of debug messages and WordPress writes each one to the browser console. Open the developer tools, switch to the Console tab, click Install Now again, and the line ending in the folder path is there. Set it back to false afterward, since debug output does not belong on a live site.

    What the Folder in the Path Tells You

    • A path under wp-content/upgrade means the unpack step failed. Check the account limits first, then whether wp-content accepts new folders.
    • A path under wp-content/plugins or wp-content/themes means the unpack worked and the final folder was refused.
    • A path outside the usual wp-content folder means WP_CONTENT_DIR in wp-config.php points elsewhere. Check that the folder it names exists and is yours.

    Why a Full Account Says Could Not Create Directory

    This is the cause the usual guides miss, and where PHP runs as your own user it is the first one to rule out. An account at its disk or file limit cannot create a folder, and WordPress has no separate message for that during a normal install. Two details in the code explain why the failure arrives in this exact form.

    The Disk-Space Check Only Runs in the Background

    WordPress does contain a clearer message: Could not copy files. You may have run out of disk space. It only checks for it while running scheduled tasks, which in practice means automatic background updates. An install or update you start by clicking a button skips that check entirely. The check also reads free space on the whole disk, not what is left in your account, so even in the background it can miss a full account.

    Folders Are Created Before Any File

    When WordPress unpacks a zip, it first lists every folder the package needs, creates all of them, and only then writes the files. Each folder takes one inode, the slot a server uses to track one file or folder. An account a few hundred inodes from its ceiling therefore fails on a folder, not a file, and the message reads Could not create directory rather than Could not copy file. Our guide to the WordPress inode limit on shared hosting explains how an account fills its file slots with gigabytes still free.

    What the Server Actually Said

    The operating system does give a reason when it refuses a folder. The Linux mkdir(2) manual page lists them, and these are the ones a hosting account meets. WordPress shows all of them as the same sentence.

    Reason codeWhat the manual saysWhat it means on hostingWhere to check
    EDQUOTThe user quota of disk blocks or inodes is exhaustedThe account is at its disk or file limitDisk Usage and File Usage in cPanel
    ENOSPCNo room for the new directory, or the disk quota is exhaustedThe same, reported differently by some filesystemsDisk Usage in cPanel
    EACCESThe parent directory does not allow write permissionFolder mode too low, or the folder belongs to another userPermissions column in File Manager
    EEXISTThe pathname already exists, not necessarily as a directoryA file is sitting where a folder should goThe exact path from the error
    Why the server refuses a new folder — the mkdir reasons WordPress turns into one sentence.

    Read Both Meters in cPanel

    The cPanel sidebar shows Disk Usage and File Usage as separate figures, and either one at its limit blocks a new folder. The cPanel Disk Usage documentation notes that only your hosting provider can raise the quota itself. A plugin also needs more room than its zip suggests: the archive and its unpacked copy exist at the same moment, and the background check above asks for a little over twice the unpacked size. The same limit is behind the upload error described in our guide to Missing a temporary folder.

    When Could Not Create Directory Really Is Permissions

    Permissions are still a real cause, just not the first one to check. The test is simple: PHP needs write permission on the parent of the folder in the path. If it lacks it, the refusal is immediate, whatever the quota says.

    The Modes WordPress Expects

    Folders belong at 755 and files at 644. WordPress itself creates new folders at no less than 755. The ArchWiki page on file permissions makes the point that matters here: creating a file changes the directory, not the file, which is why write permission on the parent is what counts. The usual ways a parent loses it are a security plugin that hardens wp-content to 555, or a manual change that was never undone.

    Why chmod 777 Is the Wrong Fix

    A top-voted forum answer is to make wp-content 777. Mode 777 grants write access to three classes: the owner, the group, and everyone else. Red Hat’s guide to Linux file permissions explains that the third class, others, covers every account that is neither the owner nor in the group. On a shared server, that is every other process. When PHP runs as your own user, 755 already lets WordPress write. If 755 fails, the folder belongs to someone else or the account is full, and 777 fixes neither.

    Ownership After a Migration or Restore

    A folder owned by another user cannot be fixed with any mode you are allowed to set, because only the owner can change it. This is the same fault that makes WordPress ask for FTP details instead of writing directly, covered in our guide to WordPress asking for FTP credentials. Our knowledge base article on file permissions and ownership explains why ownership has to be corrected on the server side.

    “Could Not Create the upgrade-temp-backup Directory” on Updates

    Updates have a related message. Since WordPress 6.3, an update first moves the current version of the plugin or theme into wp-content/upgrade-temp-backup, so it can be restored if the new version fails. If that folder cannot be made, the update stops with Could not create the upgrade-temp-backup directory, and unlike the install error it carries no path, because the folder is always the same one.

    Site Health tests this folder and marks problems as critical, but it only checks whether the folders exist and are writable. A writable folder in an account that is out of space or files passes that test and still fails the update. Check the same two meters before changing anything. An update that stops halfway can also leave the site showing the maintenance notice, which our guide to briefly unavailable for scheduled maintenance clears safely.

    How to Fix Could Not Create Directory, in Order

    Work through these in sequence. Each step either fixes the error or rules out a cause, and the order puts the checks you can make yourself first.

    1. Get the path. Install the zip through Upload Plugin, or turn on WP_DEBUG and read the browser console.
    2. Read Disk Usage and File Usage in cPanel. If either is near its limit, delete old backups, cache folders and unused plugins or themes, then retry.
    3. Open the folder from the path in the File Manager and check the Permissions column on it and on wp-content. Set folders to 755.
    4. Check that the name in the path is not already taken by a file. If it is, rename or remove that file.
    5. If a mode will not change, the folder is owned by another user. Stop there and contact your host.
    What you foundCauseFirst fix
    File Usage near its limitNo free inodes for the unpacked foldersDelete backups, caches and unused plugins, then retry
    Disk Usage near its limitNo room for the zip and its unpacked copyFree space or move to a larger plan
    Path under wp-content/upgrade, meters finewp-content or upgrade not writableSet both to 755
    Path under plugins or themes, meters fineThe destination folder is not writableSet it to 755
    A mode that will not changeThe folder belongs to another userContact your host with the full line
    Everything above checks outA layer outside the accountContact your host with the path and the time
    The AHosting Could Not Create Directory Decoder — what the path and the cPanel meters show, the cause, and the first fix.

    Could Not Create Directory Decoder

    Four questions about the failed install and your cPanel meters. The answer names the most likely reason the folder was refused and the next thing to do.

    —

    Most likely:

    Do this next:

    Read from the WordPress 7.1.2 source. It cannot see your server, so treat the answer as where to start, not as a diagnosis.

    Could Not Create Directory on AHosting Servers

    On our shared servers PHP runs as your own cPanel user, so WordPress writes to its own folders directly and needs no FTP details. We checked how often ownership goes wrong rather than assuming: a scan of all 530 docroots on one shared server found exactly two files owned by anyone other than the account, both one-off manual uploads. Each account’s temporary folder also sits inside its own quota, so the download and the unpack draw on the same allowance.

    That is why, on our WordPress hosting plans and standard web hosting plans, the meters come first and the permissions second. If the folder is yours, the account has room and the install still fails, open a ticket with the full line, path included, and we will look at it with you.

    A site that keeps running into its disk or file allowance has outgrown the plan rather than broken it. A VPS with full root access puts storage, ownership and quotas in your hands. One failed install is not a reason to move; a site that fills its allowance every few months might be.

    A Practical Checklist for Could Not Create Directory

    • Write down the full message, and whether it came from an install or an update.
    • Get the path through Upload Plugin, or through WP_DEBUG and the browser console.
    • Note which step failed: unpacking into wp-content/upgrade, or installing into plugins or themes.
    • Read Disk Usage and File Usage in cPanel before touching any permissions.
    • Free space or files if either meter is near its limit, then retry.
    • Set wp-content and the folder in the path to 755, never 777.
    • Check that no file has taken the name of the folder in the path.
    • For the upgrade-temp-backup message, check the same meters and the Site Health result.
    • Turn WP_DEBUG off again when you are finished.
    • Contact your host only when the folder is yours, the meters have room and the error remains.

    Frequently Asked Questions: Could Not Create Directory

    What does Installation failed: Could not create directory mean in WordPress?

    In other words, PHP asked the server for a new folder and the server refused. WordPress needs new folders twice during an install, once to unpack the zip under wp-content/upgrade and once to place the plugin or theme in its final folder. The message names neither the folder nor the reason. Get the path first, then check whether the account is out of space or files before you touch any permissions.

    Which folder does WordPress fail to create when a plugin install fails in 2026?

    Typically one of two. In WordPress 7.1.2 the unpack step creates a working folder under wp-content/upgrade and every folder inside the zip, and the install step creates the final folder under wp-content/plugins or wp-content/themes. The error carries the full path, but the Install Now button does not show it. Uploading the same zip from the Add New screen prints the path after the message.

    Could not create directory vs Could not copy file: what is the difference in WordPress?

    In practice they are the same kind of failure at different moments. While unzipping, WordPress creates every folder in the package first and only then writes the files. If a folder cannot be made you see Could not create directory, and if all the folders fit but a file cannot be written you see Could not copy file. On an account near its file ceiling, the folder step usually fails first.

    Disk space vs inode limit: which one causes could not create directory on shared hosting?

    Notably, either one can. A new folder needs one free file slot and a little space, and the Linux mkdir call fails when the user quota of disk blocks or of inodes is exhausted. Because a plugin unpacks into hundreds or thousands of files, an account that still has gigabytes free can run out of file slots partway through. Check both the Disk Usage and the File Usage figures in cPanel.

    Why does could not create directory appear when cPanel shows free disk space?

    Typically because the file count, not the space, is full. Every file and folder uses one inode, and hosting accounts cap how many they may hold. In addition, the clearer out of disk space message in WordPress is only checked during background updates, so an install you start by hand reports a full account as a folder it could not create. Clear old backups, caches or unused plugins, then retry.

    Is chmod 777 on wp-content a safe fix for could not create directory?

    Fortunately you never need it. Mode 777 lets every account and process on the server write into the folder, which is exactly what file permissions exist to prevent. When PHP runs as your own user, as it does on our shared servers, 755 on folders already lets WordPress create what it needs. If 755 does not work, the folder belongs to someone else or the account is full, and 777 fixes neither.

    How do I see the full error path in WordPress 7.1 in 2026?

    First and foremost, repeat the install through Plugins, Add New, Upload Plugin with the zip downloaded from the plugin page. That screen prints the message followed by the folder it failed on. Alternatively, set WP_DEBUG to true in wp-config.php, open the browser developer console and click Install Now again, because WordPress then writes the full messages, path included, to the console. Turn WP_DEBUG off afterward.

    Does AHosting shared hosting let WordPress create plugin folders directly in 2026?

    Indeed it does. On AHosting servers PHP runs as your own cPanel user, so WordPress writes to its own folders directly and needs no FTP details. In a scan of every docroot on one of our shared servers, only two files across 530 sites belonged to anyone else. That is why, on our servers, a full disk or file allowance is the first thing to check when a folder cannot be created.

    Can AHosting support fix could not create directory on my WordPress site?

    Above all, run the three checks in this guide first, because each one rules out a cause: get the full path, read both cPanel usage meters, and confirm the folder modes are 755. If the folder is yours, the account has room and the install still fails, open a ticket with the full line, path included, and we will look at it with you.

    Do I need an AHosting VPS to stop WordPress plugin install errors in 2026?

    Fortunately not for this error alone. The causes this guide covers, a full account and a changed folder mode, are both fixed inside the account. A VPS makes sense when a site keeps outgrowing its disk or file allowance, or when you need root access to manage ownership and quotas yourself.

    October 5, 2026
  • The Authorization Header Is Missing? What Site Health Tested, and the Fix

    The Authorization Header Is Missing? What Site Health Tested, and the Fix

    • What “The Authorization Header Is Missing” Actually Tests
      • Site Health Sends Its Own Test Login
      • Where It Sits on the Site Health Screen
    • Missing or Invalid: Two Labels, Two Different Faults
      • Why “Invalid” Points Somewhere Else
    • Does the Authorization Header Warning Matter on Your Site?
      • What Actually Breaks When the Header Is Lost
      • When the Authorization Header Is Missing and It Is Safe to Leave
    • Why the Authorization Header Is Missing on CGI and FastCGI Servers
      • The Two Halves of the WordPress Fix
      • What That Means on LiteSpeed
    • Why “Flush Permalinks” Sometimes Leaves the Authorization Header Missing
      • A File PHP Cannot Write
      • Multisite Networks Built Before 5.6
    • How to Add the Authorization Rule by Hand
      • Is It Safe to Edit Inside the WordPress Markers?
    • Prove the Header Reaches WordPress With an Application Password
      • Why the Authorization Header Is Missing Can Hide a REST Failure
    • When the Authorization Header Is Missing Because of the Server
    • A Practical Checklist When the Authorization Header Is Missing
    • Frequently Asked Questions: The Authorization Header Is Missing
      • What does the authorization header is missing mean in WordPress Site Health?
      • What request does Site Health send to test the Authorization header in 2026?
      • The authorization header is missing vs invalid: what is the difference in Site Health?
      • Flushing permalinks vs editing .htaccess by hand: which fixes the Authorization header warning?
      • Why does the authorization header is missing come back after I flush permalinks?
      • Is it safe to ignore the authorization header is missing if no app connects to my site?
      • How do I check that the Authorization header reaches WordPress 7.1 in 2026?
      • Does AHosting LiteSpeed hosting pass the Authorization header to WordPress in 2026?
      • Can AHosting support help when Site Health says the authorization header is missing?
      • Do I need an AHosting VPS to use WordPress application passwords in 2026?
    TL;DR

    The authorization header is missing means Site Health sent its own test login in an Authorization header and PHP never received it, so the web server or the PHP handler dropped it. No plugin sent it and no visitor is affected; it matters only to apps that log in with an application password. WordPress fixes it with one rewrite rule that “Flush permalinks” writes, except in four cases where the flush cannot write anything. Then prove it worked with a real application password, not with the warning.

    What “The Authorization Header Is Missing” Actually Tests

    The authorization header is missing is a Site Health result most site owners meet without ever having connected an app to WordPress, which is why it is confusing. The text under it talks about “third-party applications you have approved”, and the common advice is to disable plugins until it goes away. Read against the code that produces it, that advice misses: during the test, the third-party application is Site Health itself, and no plugin is involved. The result tells you one thing, that a header did not reach PHP, and whether that matters depends entirely on what logs in to your site.

    Listen: the third-party app in the warning is Site Health’s own test login, and the fix is a single rewrite rule that a permalink flush cannot always write. By Matt Chrust, Director of Business Development, AHosting.

    Site Health Sends Its Own Test Login

    An Authorization header is how a program proves who it is on each request, without a login form or a cookie. The Basic form is a username and password joined by a colon and encoded, which is exactly how Postman sets Basic auth on a request and how curl sends it with -u. The Site Health test, documented in the code reference and introduced in WordPress 5.6, sends that header from your browser to a REST route on your own site, carrying the deliberately fake pair user and pwd. Once it arrives, the route checks two PHP variables:

    • $_SERVER['PHP_AUTH_USER'] must equal user.
    • $_SERVER['PHP_AUTH_PW'] must equal pwd.
    • If both are absent, the label reads The authorization header is missing.
    • If they hold anything else, it reads The authorization header is invalid.

    Where It Sits on the Site Health Screen

    Both failure labels carry the blue Security badge and the status recommended, not critical. They sit under the async tests, so the result appears a moment after the screen loads. The test is also skipped entirely when the site itself sits behind an HTTP password, because the outer password would replace the test pair. A password-protected staging copy never shows this result, while the same site on its live domain can.

    Where the Authorization header gets lost, and how the rewrite rule carries it through Site Health sends Authorization: Basic with the pair user and pwd to its own REST route. The request passes the web server, then the PHP handler, then reaches WordPress, which looks for PHP_AUTH_USER and PHP_AUTH_PW. On the top path there is no rule: a CGI or FastCGI handler does not pass the header, the variables are empty, and the label is The authorization header is missing. On the bottom path the WordPress rewrite rule copies the header into the HTTP_AUTHORIZATION environment variable, which survives the handler, and WordPress copies it into PHP_AUTH_USER and PHP_AUTH_PW at load time. The label is The Authorization header is working as expected. Where the Authorization header gets lost. The same test request, without and with the WordPress rewrite rule (WordPress 7.1.2). Site Health sends Authorization: Basic user:pwd to its own REST route NO RULE Web server receives the header CGI / FastCGI handler does not pass it on PHP_AUTH_USER empty header is missing WITH THE WORDPRESS RULE Rewrite rule copies it into HTTP_AUTHORIZATION Handler passes the variable to PHP WordPress fills PHP_AUTH_USER: test passes The label only says the header did not arrive. It does not say which layer dropped it.

    Missing or Invalid: Two Labels, Two Different Faults

    The two failure labels look like the same complaint, but they come from different branches of the check and point at different layers. Knowing which one you have rules out half the causes before you open a file.

    LabelWhat PHP receivedStatusWhat usually causes itWhat can fix it
    The authorization header is missingNo Basic credentials at allRecommendedA CGI or FastCGI handler that does not pass the header, with no rule to carry itThe rewrite rule, written by a flush or by hand
    The authorization header is invalidCredentials, but not user and pwdRecommendedA folder password, a proxy or a security layer that sets its own headerRemoving or excluding the layer that replaced it
    The Authorization header is working as expectedExactly user and pwdGoodNothingNothing to fix
    The three Authorization header results in Site Health — what WordPress 7.1.2 checks and which layer each result points at.

    Why “Invalid” Points Somewhere Else

    An invalid result means the header did get through, so the rewrite rule is not the problem. Something swapped the credentials on the way. On a cPanel account the usual source is Directory Privacy, which puts a real password on the folder: the browser then sends those credentials instead of the test pair. A proxy that adds its own Authorization header does the same. Flushing permalinks cannot touch either one.

    Does the Authorization Header Warning Matter on Your Site?

    Here is the question none of the usual guides ask. The header only matters to programs that log in with HTTP Basic credentials, and in WordPress core that means application passwords. Your visitors, the block editor and your own admin login all use cookies, so when the authorization header is missing none of them notice anything.

    What Actually Breaks When the Header Is Lost

    Application passwords are separate credentials WordPress issues for programs, and the core integration guide notes that by default they are available only on sites served over SSL. They work on REST API and XML-RPC requests only. When the header is lost, every one of these fails with a login error even though the password is correct:

    • Automation tools. n8n’s WordPress credential, for example, asks for a username and an application password.
    • Remote publishing apps and scripts that post through the REST API.
    • WooCommerce’s own REST API keys, which its documentation sends as HTTP Basic auth, and which fail with “Consumer key is missing” on servers that do not parse the header.

    When the Authorization Header Is Missing and It Is Safe to Leave

    If nothing connects to the site that way, leaving the warning alone has no effect on how the site runs, and some owners switch application passwords off on purpose because they authenticate without passing through the login form. That is a security choice, and a reasonable one. What is not reasonable is guessing: a plugin you install next month may depend on the header. Our knowledge base article on securing the REST API and XML-RPC covers how to keep application passwords tidy if you do use them.

    Why the Authorization Header Is Missing on CGI and FastCGI Servers

    The code itself names the cause. The WordPress function that repairs the header carries the comment that some servers running in CGI or FastCGI mode do not pass the Authorization header on to WordPress. When PHP runs as a separate process from the web server, which is how most shared hosting runs it, the server decides which request headers become PHP variables, and some servers do not pass this one on.

    The Two Halves of the WordPress Fix

    WordPress works around it in two steps. First, the rewrite block it writes to .htaccess contains RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}], which copies the incoming header into a server variable called HTTP_AUTHORIZATION. The E= flag, as the Apache rewrite flags manual explains, sets an environment variable, and after an internal rewrite the server renames it with a REDIRECT_ prefix. Second, early in every page load, WordPress reads HTTP_AUTHORIZATION or REDIRECT_HTTP_AUTHORIZATION, decodes the Basic pair and fills PHP_AUTH_USER and PHP_AUTH_PW itself.

    What That Means on LiteSpeed

    Our shared servers run LiteSpeed with PHP as a separate process under each site’s own user. WordPress counts LiteSpeed as Apache: its server check is true for either name, so Site Health shows the Flush permalinks action and WordPress writes the rule into .htaccess exactly as it would on Apache. Whether the header then arrives on your site is not something to assume either way. The application password test further down answers it in about a minute.

    Why “Flush Permalinks” Sometimes Leaves the Authorization Header Missing

    Every guide on the first page of results says to flush permalinks, and often that works: saving Settings, Permalinks rewrites the WordPress block, and that block has carried the Authorization rule since 5.6. But the flush fails silently in four situations, and in each one the authorization header is missing after the flush exactly as before.

    SituationWhat the flush doesWhyWhat to do instead
    .htaccess not writableNothing, and no messageWordPress writes only when the file, or its folder if the file is absent, is writable by PHPFix ownership, then flush again, or edit by hand
    Plain permalinks (?p=123)Writes an empty blockWith no pretty permalinks WordPress generates no rewrite rules at allChoose a pretty structure, or add the line by hand
    Multisite networkNothing at allSaving permalinks never writes .htaccess on MultisiteAdd the line by hand to the network file
    nginxNo flush action is offerednginx does not read .htaccess, so there is nothing to writeChange the server configuration
    When flushing permalinks cannot fix the Authorization header — four cases read from the WordPress 7.1.2 source.

    A File PHP Cannot Write

    The first case is the most common on accounts that were moved or restored by hand. If .htaccess belongs to a different user than the one PHP runs as, WordPress cannot rewrite it and simply skips the step. The same ownership fault is what makes WordPress ask for FTP details, and our guide to WordPress asking for FTP credentials shows how to spot it.

    Multisite Networks Built Before 5.6

    A network’s .htaccess comes from the block the Network Setup screen tells you to paste, and the current block includes the Authorization rule. A network set up before WordPress 5.6 was given a block without it, and nothing has updated the file since. Our page on WordPress Multisite hosting covers what else differs on a network.

    How to Add the Authorization Rule by Hand

    When the flush cannot write, add the line yourself. It takes two minutes in the cPanel File Manager, and it is the same line WordPress would have written.

    1. Open the File Manager, turn on hidden files, and open .htaccess in the WordPress folder.
    2. Find the block that starts # BEGIN WordPress and the line RewriteEngine On inside it.
    3. Directly below RewriteEngine On, add RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] on its own line, unless it is already there.
    4. Save, reload Site Health, and wait a moment for the async tests to run again.

    Is It Safe to Edit Inside the WordPress Markers?

    Normally anything between # BEGIN WordPress and # END WordPress is overwritten on the next flush. Here that is harmless, because the line you added is the line WordPress writes itself: a later successful flush puts it back in the same place. On Multisite the markers are yours, and the line goes directly after RewriteEngine On in the block the Network Setup screen shows.

    Prove the Header Reaches WordPress With an Application Password

    The warning is a proxy for the thing you actually care about, which is whether a real program can log in. Test that directly. Under Users, Profile, create an application password named header test, then run one request from your own computer:

    • curl -u yourname:"xxxx xxxx xxxx xxxx xxxx xxxx" https://example.com/wp-json/wp/v2/users/me
    • Replace the name, the password WordPress showed you, and the domain.
    • Read the status and the code field in the reply, then revoke the test password.
    What came backWhat it meansFirst fix
    200 with your user detailsThe header arrived and the password workedNothing; the warning should clear after the rule is in place
    401 rest_not_logged_inWordPress saw no credentials: the header was dropped, or application passwords are switched offConfirm the rule is in .htaccess, then check whether a security plugin disables application passwords
    401 incorrect_passwordThe header arrived; the password did not matchCopy the password again, spaces and all
    401 invalid_usernameThe header arrived; the username did not matchUse the login name, not the display name
    401 application_passwords_disabled_for_userThe header arrived; the feature is off for that userCheck any plugin or setting that limits application passwords by role
    403 or an HTML pageSomething in front of WordPress refused the requestRead the security plugin and firewall logs for the time of the test
    The AHosting Authorization Header Decoder — what an application password request returns, what it proves about the header, and the first fix.

    Authorization Header Decoder

    Four questions about your site and what Site Health printed. The answer names the most likely reason the header is lost and the next thing to do.

    —

    Most likely:

    Do this next:

    Read from the WordPress 7.1.2 source. It cannot see your server, so treat the answer as where to start, not as a diagnosis.

    Why the Authorization Header Is Missing Can Hide a REST Failure

    The Site Health test is itself a REST request, so if the REST API is blocked the header check cannot pass either. When the REST test on the same screen is also red, start with our guide to the REST API encountered an error. If you restricted the REST API on purpose, stopping REST API user enumeration shows how to close the risky parts without breaking authenticated requests.

    When the Authorization Header Is Missing Because of the Server

    Most cases end at the manual rule. On our WordPress hosting plans and standard web hosting plans WordPress treats the server as Apache, so the flush action is offered and the rule goes into .htaccess like on any Apache host. What remains is the case you cannot settle from inside the account: the line is in place, the application password test still returns rest_not_logged_in, and no plugin disables the feature. If the header still does not arrive after the rule is in place, open a ticket with the line Site Health printed and we will look at it with you.

    Some setups need a change to the web server itself, such as a reverse proxy that strips the header or a handler setting, and no file inside a shared account can reach that. A VPS with full root access puts that configuration in your hands. One recommended item in Site Health is not a reason to move; an integration you depend on that cannot authenticate might be. If both the loopback and REST tests are failing as well, our guide to the failed loopback request is the place to start.

    A Practical Checklist When the Authorization Header Is Missing

    • Note whether the label says missing or invalid before changing anything.
    • Decide whether anything logs in with an application password or REST API keys.
    • If the label is invalid, check cPanel Directory Privacy and any proxy in front of the site.
    • Open .htaccess and search for the HTTP_AUTHORIZATION line.
    • If it is absent, save Settings, Permalinks once and look again.
    • If it is still absent, check ownership, the permalink setting and whether it is Multisite.
    • Add the line by hand, directly after RewriteEngine On.
    • Run the application password test and read the code in the reply.
    • Revoke the test password when you are done.
    • Open a ticket only when the line is present and the test still returns rest_not_logged_in.

    Frequently Asked Questions: The Authorization Header Is Missing

    What does the authorization header is missing mean in WordPress Site Health?

    In other words, PHP never received the login details Site Health sent to test it. The check sends its own made-up username and password in an Authorization header to a REST endpoint on your site, then looks for them in the PHP variables WordPress reads. When they are absent, the web server or the PHP handler dropped the header on the way. It matters only for apps that log in with an application password, and the fix is one rewrite rule.

    What request does Site Health send to test the Authorization header in 2026?

    Specifically, a REST request from your browser to the authorization-header test route under wp-json, carrying the header Authorization: Basic with the encoded pair user and pwd. In WordPress 7.1.2 the route then checks whether PHP_AUTH_USER equals user and PHP_AUTH_PW equals pwd. The test is skipped entirely when the site itself sits behind an HTTP password, because those credentials would replace the test pair.

    The authorization header is missing vs invalid: what is the difference in Site Health?

    In practice the first means nothing arrived and the second means the wrong thing arrived. Missing is shown when PHP has no Basic credentials at all, so the header was dropped between the server and WordPress. Invalid is shown when credentials did arrive but they were not user and pwd, so something in the path replaced them, such as a password on the folder or a proxy that sets its own header.

    Flushing permalinks vs editing .htaccess by hand: which fixes the Authorization header warning?

    Typically flushing is enough, because it rewrites the WordPress block of .htaccess and that block has carried the Authorization rule since WordPress 5.6. Editing by hand is needed when the flush cannot write: the file is not writable, the site uses plain permalinks, or it is a Multisite network, where the flush writes nothing at all. In those cases add the single rewrite line yourself, directly after RewriteEngine On.

    Why does the authorization header is missing come back after I flush permalinks?

    Typically because the flush did not write anything. WordPress saves the rules only when .htaccess or its folder is writable, writes an empty block on plain permalinks, and skips the file entirely on Multisite. Open .htaccess and look for the line containing HTTP_AUTHORIZATION. If it is absent, the flush failed silently. If it is present and the warning stays, the server is dropping the header before the rule can run.

    Is it safe to ignore the authorization header is missing if no app connects to my site?

    Indeed it is, as long as nothing logs in to the site with HTTP Basic credentials. Visitors, the block editor and your own admin login use cookies, not this header, so they are unaffected. What breaks is anything that uses an application password, such as an automation tool, a remote publishing app or a script, along with integrations like the WooCommerce REST API that send keys the same way.

    How do I check that the Authorization header reaches WordPress 7.1 in 2026?

    First and foremost, test the real feature rather than the warning. Create an application password under your user profile, send one request with curl using your username and that password to the users me endpoint under wp-json, then revoke the password. A 200 with your user means the header arrived. A 401 with rest_not_logged_in means it was dropped, while incorrect_password or invalid_username mean it arrived and the credentials were wrong.

    Does AHosting LiteSpeed hosting pass the Authorization header to WordPress in 2026?

    Notably, WordPress treats LiteSpeed the same way it treats Apache, so on AHosting shared and WordPress plans Site Health offers the Flush permalinks action and writes the Authorization rule into .htaccess when permalinks are pretty and the file is writable. Whether your own site receives the header is a one-minute check with the application password test in this guide. If the rule is present and the test still fails, contact support.

    Can AHosting support help when Site Health says the authorization header is missing?

    Above all, try the two steps in this guide first, because together they settle most cases: confirm the rewrite line is in .htaccess, then run the application password test. If the line is in place and the test still returns rest_not_logged_in, the header is being lost before WordPress runs, which you cannot change from inside the account. In that case open a ticket with the line Site Health printed and we will look at it with you.

    Do I need an AHosting VPS to use WordPress application passwords in 2026?

    Fortunately not for the header alone. Application passwords need HTTPS and a server that passes the Authorization header through, and on shared hosting the rewrite rule in this guide is the usual way to get it. A VPS makes sense when you need to change the web server configuration itself, for example a proxy or a handler setting, which no account-level file can reach.

    October 4, 2026
  • The REST API Encountered an Error? WordPress Never Reached It

    The REST API Encountered an Error? WordPress Never Reached It

    • What “The REST API Encountered an Error” Actually Tests
      • The Request Site Health Sends
      • It Goes to the Home URL, Not the WordPress Address
    • Three Labels, Three Failures: Which REST API Result Do You Have?
      • What Site Health Prints, and What It Leaves Out
      • Why a 200 Web Page Counts as Misbehaving
    • What Our Own Blog Returned When We Sent the Same Request
      • Why Your Browser Gets a 401 Even When You Are Logged In
    • The REST API Encountered an Error: The Request Never Arrived
      • DNS and the Home URL During a Migration
      • Ten Seconds and Two Entry Processes
      • Why Flushing Permalinks Cannot Fix The REST API Encountered an Error
    • The REST API Encountered an Unexpected Result: Reading the Status
      • Why a 401 Here Is Almost Never WordPress
      • Turning the REST API Off Is Not the Same as Restricting It
    • The REST API Did Not Behave Correctly: A 200 That Is Not WordPress’s Answer
      • Dropped Query Strings, Redirects and Stored Copies
    • How to Fix The REST API Encountered an Error, in Order
      • Testing It Properly From the Block Editor
    • When The REST API Encountered an Error Is the Server, Not the Site
    • A Practical Checklist for a Failed REST API Test
    • Frequently Asked Questions: The REST API Encountered an Error
      • How do you fix an API error like the REST API encountered an error in WordPress?
      • What request does Site Health send when it reports the REST API encountered an error in 2026?
      • The REST API encountered an error vs an unexpected result: what is the difference?
      • Loopback request failed vs the REST API encountered an error: why can one pass while the other fails?
      • Why does wp-json show a 401 error in my browser when I am logged in to WordPress?
      • Will flushing permalinks fix the REST API encountered an error in Site Health?
      • What does REST API did not behave correctly mean in a WordPress 7.1 site in 2026?
      • Does AHosting block the WordPress REST API on its shared hosting plans in 2026?
      • Can AHosting support help when Site Health says the REST API encountered an error?
      • Should I move to an AHosting VPS if the REST API test keeps timing out in 2026?
    TL;DR

    The REST API encountered an error means Site Health’s test request got no answer at all, so the REST API never ran. Permalinks and plugins cannot cause that; DNS, a firewall or a timeout can. The two other labels are different failures: “unexpected result” is a status code, and “did not behave correctly” is a 200 that was not WordPress’s answer. Read the line under the label, then read the code inside the response body, which Site Health never shows you.

    What “The REST API Encountered an Error” Actually Tests

    The REST API encountered an error is the critical result on the Site Health screen, and the usual advice is to flush permalinks and deactivate plugins until it goes away. Read against the code that produces it, that advice mostly misses. This label appears only when Site Health’s test request got no response at all, which means WordPress never ran and nothing a plugin does could have caused it. The two other REST labels on the same screen are different failures with different fixes, and the one thing that tells them apart is a line most people skip.

    Listen: the critical REST API result means Site Health’s request never got an answer, so the fix is in DNS, a firewall or a timeout rather than in permalinks. By Matt Chrust, Director of Business Development, AHosting.

    The Request Site Health Sends

    The REST API is the interface the block editor uses to load and save content, and the Learn WordPress tutorial on it shows the basic shape: requests go to addresses under /wp-json/ and the answers come back as JSON. Site Health checks it with one request, and the method that runs it in WordPress 7.1.2 sets every detail:

    • A GET to /wp-json/wp/v2/types/post with ?context=edit, the view the editor itself asks for.
    • Your own login cookies, copied from the admin page you are looking at.
    • An X-WP-Nonce header, the token that proves the request came from your session.
    • A Cache-Control: no-cache header and a ten-second limit.
    • Certificate checks switched off, so an expired or self-signed certificate does not fail it.

    It Goes to the Home URL, Not the WordPress Address

    The address is built from your Site Address, the home URL, not from the WordPress Address where the core files live. The loopback test on the same screen does the opposite and posts to wp-cron.php on the WordPress Address. On most sites the two are identical. Where they differ, for example WordPress installed in a subfolder but served from the domain root, one test can pass while the other fails, because they never touched the same address. Settings, General shows both.

    One request, three ways for the Site Health REST API test to fail Site Health sends one GET request to the wp-json posts type route on the home URL, with context set to edit, the admin cookies, a REST nonce and a ten second limit. Three outcomes branch from it. If no response arrives, the label is The REST API encountered an error, marked critical, and WordPress never ran. If a response arrives with a status other than 200, the label is The REST API encountered an unexpected result. If a 200 arrives without the capabilities field, the label is The REST API did not behave correctly. Only a 200 with capabilities passes. One request, three ways to fail. What the WordPress 7.1.2 Site Health REST test sends, and which label each outcome produces. GET /wp-json/wp/v2/types/post?context=edit (home URL) your admin cookies + X-WP-Nonce + Cache-Control: no-cache, 10-second limit No response at all encountered an error critical WordPress never ran. Look at DNS, firewall, timeouts. A status other than 200 encountered an unexpected result recommended Something answered. Read the body: JSON code or an HTML page? 200 without capabilities did not behave correctly recommended Not WordPress’s answer: a redirect, a dropped query string, a copy. Only a 200 carrying a capabilities field passes. Site Health shows the status text, never the REST error code in the body.

    Three Labels, Three Failures: Which REST API Result Do You Have?

    WordPress decides between the labels in a fixed order, and each step answers a different question about the response. Knowing whether you have the REST API encountered an error or one of the two other labels rules out most causes before you open a single file.

    LabelSeverityWhat the test sawDid WordPress run?What can fix it
    The REST API encountered an errorCriticalNo response: the HTTP request itself failedNoDNS, firewall, network path, timeouts
    The REST API encountered an unexpected resultRecommendedA response with a status other than 200Sometimes; the body tells youWhatever the body names
    The REST API did not behave correctlyRecommendedA 200 whose body has no capabilities fieldUsually not for this requestRedirects, caches, query-string handling
    The REST API is availableGoodA 200 carrying the edit viewYesNothing to fix
    The three REST API results in Site Health — how WordPress 7.1.2 chooses each label, and which layer it points at.

    What Site Health Prints, and What It Leaves Out

    Under the label sits a line beginning REST API Response:. For the critical result it carries the transport error, such as a cURL timeout. For an unexpected result it carries only the status and its standard text, for example (403) Forbidden. What it never prints is the body of the response, and that is a problem, because a 403 written by WordPress and a 403 written by a firewall look identical in that line. One is a JSON object with a named error code. The other is a web page.

    Why a 200 Web Page Counts as Misbehaving

    The third label is decided by decoding the body and looking for a key called capabilities, which only the edit view contains. The code is written to skip that check when decoding fails, but json_decode returns null on input that is not JSON, never false, so the skip never happens. A login page or a holding page that arrives with a 200 status therefore lands in “did not behave correctly”, not in an error. That is useful to know, because it means this label covers two quite different situations: JSON that is missing a field, and a response that was never JSON at all.

    What Our Own Blog Returned When We Sent the Same Request

    To show what each answer looks like in practice, we sent the test’s request to the AHosting blog on 2 October 2026, from outside the server and through Cloudflare, in four variations. None was logged in, which is the point: these are the responses a test sees when the login does not arrive with the request. All four matched the WordPress 7.1.2 source exactly.

    Request we sentStatusCode in the bodyWhat it shows
    The test URL, no login, no nonce401rest_forbidden_contextWhat a browser address bar gets: no nonce means logged out
    The same URL without context=edit200None; post type JSON without capabilitiesWhat the third label sees when the context is lost
    The test URL, an invalid nonce and a cookie that does not log in403rest_cookie_invalid_nonce, Cookie check failedWhat Site Health gets when your login does not reach WordPress
    The plain-permalink form, ?rest_route=401rest_forbidden_contextThe API answers without any rewrite rules
    Four requests to the AHosting blog’s REST API, 2 October 2026, each response read from the headers and body.

    Why Your Browser Gets a 401 Even When You Are Logged In

    The first row catches people out. Paste the test URL into a browser where you are signed in and you still get a 401, which looks like proof the REST API is broken. It is not. As the REST API authentication handbook says, if no nonce is provided the API sets the current user to 0, turning the request into an unauthenticated one even if you are logged in. An address bar sends cookies but never a nonce, so the edit view refuses it. Site Health always sends a nonce, which leads to the third row: when its cookie fails, the answer is a 403 with rest_cookie_invalid_nonce, not a 401.

    The REST API Encountered an Error: The Request Never Arrived

    When the critical label appears, the line under it holds an error from the HTTP client, usually written as a cURL error with a number. The request left WordPress, tried to reach your home URL and failed before any server sent a byte back. That narrows the search to three places: where the domain points, whether the connection was allowed, and whether anything answered within ten seconds. Our guide to the failed loopback request decodes each cURL number for the same stack, and the codes mean the same thing here.

    DNS and the Home URL During a Migration

    Since the test resolves your public domain, a site mid-migration sends it to whichever server the DNS still names. If that is the old host and it has closed the account, the connection fails and the REST API encountered an error appears. If the old copy still runs, the request reaches a different WordPress with different login keys, and you get a 403 instead. Either way the fix is DNS, not WordPress, and it resolves on its own once the domain points at the new server.

    Ten Seconds and Two Entry Processes

    The test also holds two PHP processes at once: the admin page running the check, and the REST request it makes. On our shared plans the published entry-process ceilings are up to 30 on Bronze, 40 on Silver and 50 on Gold. A page served from LiteSpeed’s cache uses none, so the slots fill only with uncached work such as wp-admin, carts and bots. When every slot is busy the request either waits past ten seconds and times out, giving the REST API encountered an error, or is refused with a 508. Our 508 guide covers what fills them.

    Why Flushing Permalinks Cannot Fix The REST API Encountered an Error

    Permalink rules decide which code handles a request once it reaches the server. A request that never reached the server is beyond their reach, so saving the Permalinks screen changes nothing for the critical label. The same goes for deactivating plugins: none of them ran. Both steps belong to the unexpected-result cases below, where something did answer.

    The REST API Encountered an Unexpected Result: Reading the Status

    An unexpected result means the request got through and something sent back a status other than 200. The status narrows it down; the body settles it. Open the response once, using the method in the fix section below, and match it against this table.

    Site Health printedBody you will findWhat answeredUsual cause on a cPanel account behind LiteSpeed and CloudLinuxFirst fix
    (401) UnauthorizedAn HTML page, with a login prompt headerThe web serverA password-protected folder (cPanel Directory Privacy)Remove the password or test without it
    (403) ForbiddenJSON: rest_cookie_invalid_nonceWordPressYour login did not reach it, or reached another copy of the siteCheck DNS, then anything that strips cookies
    (403) ForbiddenAn HTML pageA rule in front of WordPressSecurity plugin, .htaccess deny, firewall rule, proxy challengeRead that layer’s log for the test time
    (404) Not FoundJSON: rest_no_routeWordPressA plugin removed the posts routeDeactivate REST-disabling plugins one by one
    (404) Not FoundAn HTML pageThe web serverRewrite rules not sending /wp-json/ to WordPressSave Settings, Permalinks; check .htaccess
    (500) Internal Server ErrorOften empty or an error pagePHPA fatal error in code that runs on REST requestsRead the error log for the test time
    (503) or (508)An HTML pageWordPress or the serverMaintenance mode, or every entry process busyWait it out, or check resource usage
    The AHosting REST API Response Decoder — what Site Health printed, the code in the body it does not show you, and the first fix on a cPanel account.

    REST API Result Decoder

    Three questions about what Site Health printed and what the response body contains. The answer names the layer that failed and the first thing to do.

    —

    What answered:

    Do this next:

    Read from the WordPress 7.1.2 source. It cannot see your server, so treat the answer as where to start, not as a diagnosis.

    Why a 401 Here Is Almost Never WordPress

    WordPress returns 401 only to a request it treats as logged out, and a request carrying a nonce is never quietly treated that way: if the cookie fails, the nonce check fails too and the answer is 403. So on this test a 401 usually comes from the web server itself, asking for a folder password before PHP runs. Site Health forwards such a password only when PHP received one with the page that ran the test, which is why password-protected staging sites so often show this result.

    Turning the REST API Off Is Not the Same as Restricting It

    Many guides answer how to turn off the REST API in WordPress, and the answer matters here. A plugin or rule that blocks only logged-out visitors does not trip this test, because the test is logged in. One that disables the API for everyone, or removes routes, does, and so does any firewall rule matching /wp-json/ regardless of login. Our guide to stopping REST API user enumeration shows how to close the parts that leak usernames without switching the editor’s interface off.

    The REST API Did Not Behave Correctly: A 200 That Is Not WordPress’s Answer

    This label means the status was fine and the content was not. Either the JSON lacked the edit view, or the body was not JSON. In both cases something other than the REST route decided what came back, and the label’s own wording, that the API did not process the context parameter, points at the most common reason.

    Dropped Query Strings, Redirects and Stored Copies

    WordPress follows up to five redirects before it reads the body. A redirect rule that rewrites the address without carrying the query string across, for instance one that forces www or a trailing slash, delivers the request without ?context=edit. WordPress then answers correctly for the view it was asked for, a 200 without capabilities, which is our second test row. On plain permalinks the whole route lives in the query string, so the same redirect lands on the home page instead and the body is HTML. A login wall, a coming-soon plugin or a holding page reached by redirect does the same. The last case is a stored copy: a cache in front of the site that keeps a public response for /wp-json/ can hand it back to the test. Our write-up of LiteSpeed Cache behind Cloudflare covers which layer keeps what on this stack.

    How to Fix The REST API Encountered an Error, in Order

    Work from the outside in. Each step either names the layer or rules one out, and none of them involves deactivating everything and hoping.

    1. Read the full line under the label and note the cURL error or the status in brackets. That single line decides which section of this guide applies.
    2. For the critical label, check that the domain resolves to this server, then fetch /wp-json/ on the home URL with curl from your own computer. A timeout or a refused connection there confirms a network or DNS problem.
    3. For a status, read the body. A JSON object with a code field came from WordPress; an HTML page came from something in front of it.
    4. Fix the one layer the code names, using the decoder table above.
    5. Reload Site Health. The REST test runs again each time the screen loads, so the label changes as soon as the cause is gone.

    Testing It Properly From the Block Editor

    Because an address bar never sends a nonce, the honest test runs from a page that does. Open any post in the block editor, open the browser console and run wp.apiFetch({ path: '/wp/v2/types/post?context=edit' }). The editor’s fetch helper attaches your nonce and cookies automatically, so this is the request Site Health makes. A result with a capabilities object means the API works for you and the problem is specific to the server-side test. An error shows the real code. The same call on the Network tab shows headers and body together, and Firefox’s request details guide explains where each part sits. If saves are also failing with a JSON message, our guide to the not a valid JSON response error covers the editor side of the same failure.

    When The REST API Encountered an Error Is the Server, Not the Site

    Most cases end at step four with a setting, a plugin or a DNS record. On our WordPress hosting plans and standard web hosting plans the REST API is reachable by default, and a fresh install saves through it normally. What remains is the case the checks above cannot settle from inside the account: a timeout when nothing in resource usage looks busy, or a refusal you did not add and cannot find. In that case, open a ticket with the line Site Health printed and we will look at it with you.

    If the timeouts are about capacity, with entry-process faults stacking up whenever the site is busy, the shared ceiling is the real limit. A VPS with full root access removes it and puts the firewall rules, the timeouts and the PHP limits in your hands. One red line in Site Health is not a reason to move; a pattern of them under load is.

    A Practical Checklist for a Failed REST API Test

    • Note whether Site Health says the REST API encountered an error or one of the two other labels before changing anything.
    • Copy the line under it: the cURL error or the status in brackets.
    • Compare Site Address and WordPress Address under Settings, General.
    • Confirm the domain resolves to this server, especially after a migration.
    • Open the response body and decide: JSON code, or an HTML page.
    • Check cPanel Directory Privacy if the status is 401.
    • Check the security plugin, .htaccess and any proxy firewall if the 403 is HTML.
    • Look for redirects that drop the query string if the label is the third one.
    • Read the error log for a 500, and resource usage for a 508.
    • Reload Site Health after each change, not after all of them.

    Frequently Asked Questions: The REST API Encountered an Error

    How do you fix an API error like the REST API encountered an error in WordPress?

    First and foremost, read the line under the label before changing anything. Site Health prints the error code or status it received, and that line names the layer that failed. A cURL error means the request never got an answer, so look at DNS, the firewall and your account limits. A status code means something did answer, so open the response body and read the code inside it. Fix that one layer, then reload Site Health to confirm the result has changed.

    What request does Site Health send when it reports the REST API encountered an error in 2026?

    Specifically, one GET request to the posts type route under wp-json on your home URL, with context set to edit. In WordPress 7.1.2 it forwards the cookies of the admin viewing the screen, adds a REST nonce header and a no-cache header, and allows ten seconds. It then expects a 200 response whose JSON carries a capabilities field. Each of the three warning labels means one of those expectations was not met.

    The REST API encountered an error vs an unexpected result: what is the difference?

    In other words, no answer versus the wrong answer. The REST API encountered an error is the critical label, and WordPress shows it only when the HTTP request failed outright, such as a DNS failure, a refused connection or a timeout. The unexpected result label means a response did arrive but with a status other than 200. So the first points at the network path, and the second at whatever answered.

    Loopback request failed vs the REST API encountered an error: why can one pass while the other fails?

    Notably, the two tests send different requests to different addresses. The loopback test posts to wp-cron.php on the WordPress address, while the REST test requests a wp-json route on the home address with your login cookies. When the two addresses differ, or a rule only matches wp-json, one test passes and the other fails. When both fail with the same cURL error, the shared network path is the problem.

    Why does wp-json show a 401 error in my browser when I am logged in to WordPress?

    Indeed this is expected and does not mean the API is broken. A browser address bar sends your cookies but no REST nonce, and WordPress treats any cookie request without a nonce as logged out. Asking for the edit context while logged out returns 401 with the code rest_forbidden_context. Remove the context parameter and you should get a 200 with JSON, which proves the API itself is answering.

    Will flushing permalinks fix the REST API encountered an error in Site Health?

    Typically no, and the source explains why. That label appears only when no response arrived at all, and permalink rules cannot affect a request that never reached WordPress. Flushing permalinks helps in one narrower case: a 404 page made of HTML rather than JSON, on a site using pretty permalinks, which means the rewrite rules are not sending wp-json to WordPress. Sites on plain permalinks use a query string and do not need rewrites.

    What does REST API did not behave correctly mean in a WordPress 7.1 site in 2026?

    In fact it means the test got a 200 response that was not the answer WordPress gives for that request. The body either was not JSON, such as a login or holding page reached through a redirect, or was JSON without the capabilities field, which happens when something dropped the context parameter or served a stored copy. WordPress follows up to five redirects, so a 200 at the end can hide where the request went.

    Does AHosting block the WordPress REST API on its shared hosting plans in 2026?

    Fortunately no. AHosting shared and WordPress plans leave the REST API reachable by default, and a default install saves posts through it normally. What usually blocks it is something added inside the account or in front of the domain: a security plugin, a password-protected folder, a firewall service on the domain, or a hand-edited rewrite rule. That is why this guide reads the response first instead of blaming the plan.

    Can AHosting support help when Site Health says the REST API encountered an error?

    Above all, run the two checks in this guide first, because they usually find the cause in minutes: read the line under the label, then fetch the endpoint from outside the server. If the answer points at the server rather than at a plugin or a setting, such as a timeout with nothing busy or a block you did not add, open a ticket with the line Site Health printed and we will look at it with you.

    Should I move to an AHosting VPS if the REST API test keeps timing out in 2026?

    Ultimately only if the timeouts come from load rather than configuration. A test that times out because every PHP slot is busy with uncached traffic is a capacity signal, and a VPS removes the shared ceiling. A test that times out because DNS or a firewall rule sends the request nowhere will time out on any server. Fix the configuration first, then decide on capacity using what the account limits page shows.

    October 3, 2026
  • Briefly Unavailable for Scheduled Maintenance? WordPress Gives Up After 10 Minutes

    Briefly Unavailable for Scheduled Maintenance? WordPress Gives Up After 10 Minutes

    • What Briefly Unavailable for Scheduled Maintenance Actually Means
      • The Notice, Word for Word
      • What Is Inside the .maintenance File
    • Which Updates Put Your Site in Maintenance Mode, and Which Don’t
      • Why Update All Behaves Differently
    • How Long Has Briefly Unavailable for Scheduled Maintenance Been Showing?
      • Checking What the Server Actually Says
      • A Notice That Never Expires
    • “Another Update Is Currently in Progress” Is a Different Lock
      • Clearing the Core Update Lock
      • The Background Lock Nobody Sees
    • What the Interrupted Update Left Behind, and How to Put It Back
      • A Missing Plugin Is Usually in upgrade-temp-backup
      • A Critical Error Means Old and New Files Are Mixed
    • Why Updates Get Interrupted on Shared Hosting
      • The Safety Net Catches Errors, Not a Request That Dies
      • The Limits That Cause It
      • How This Plays Out on AHosting Servers
    • How to Update Without Seeing Briefly Unavailable for Scheduled Maintenance Again
      • When to Bring Us In
    • When a Server With More Room for Updates Makes Sense
    • Frequently Asked Questions: Briefly Unavailable for Scheduled Maintenance
      • How do I remove a WordPress site from maintenance mode when it says briefly unavailable for scheduled maintenance?
      • How long does briefly unavailable for scheduled maintenance last before WordPress clears it in 2026?
      • Deleting .maintenance vs waiting: which fixes briefly unavailable for scheduled maintenance faster?
      • The .maintenance file vs the update lock: what is the difference between the two WordPress update errors?
      • Why does my site still say briefly unavailable for scheduled maintenance after I deleted .maintenance?
      • A plugin vanished after briefly unavailable for scheduled maintenance: how do I get it back?
      • Does WordPress roll back a failed plugin update automatically in 2026?
      • Is it safe to click Update all on an AHosting WordPress plan in 2026?
      • Can AHosting support help when a site is stuck on briefly unavailable for scheduled maintenance?
      • Should I move to an AHosting VPS if WordPress updates keep failing in 2026?
    TL;DR

    Briefly unavailable for scheduled maintenance means a WordPress update was running and did not finish cleanly. WordPress stops honoring the notice by itself ten minutes after the update began, so deleting .maintenance only saves you those ten minutes. The real job is what the interrupted update left behind: a plugin folder moved aside, a half-copied core, or a lock that blocks the next attempt. Fix that, then update in smaller batches.

    What Briefly Unavailable for Scheduled Maintenance Actually Means

    Briefly unavailable for scheduled maintenance is the page WordPress shows visitors while it swaps files during an update. When it sticks, the advice everywhere is the same: find the hidden .maintenance file and delete it. That works, but it skips two facts. WordPress already stops honoring that file ten minutes after the update began, so deleting it buys you minutes at most. And the notice was never the damage. It is the sign that an update stopped partway, and whatever it was replacing may still be half done.

    Listen: the WordPress maintenance notice switches itself off after ten minutes, so the real repair is whatever the interrupted update left half done. By Matt Chrust, Director of Business Development, AHosting.

    The Notice, Word for Word

    The full text reads Briefly unavailable for scheduled maintenance. Check back in a minute. WordPress 7.1.2, the current release on 1 October 2026, sends it with the HTTP status 503 and a Retry-After: 600 header, which tells browsers and crawlers to come back in ten minutes. The number is not a coincidence. It matches exactly how long WordPress will keep showing the page.

    What Is Inside the .maintenance File

    Before it touches any files, the updater writes a one-line file to the folder that holds wp-config.php: <?php $upgrading = 1790888968; ?>. The number is the moment the update started, as a Unix timestamp. On every request, wp_is_maintenance_mode loads that file and compares the timestamp with the current time. If less than ten minutes have passed, the visitor gets the notice. If ten minutes or more have passed, WordPress treats maintenance as over and serves the site normally, file or no file. It does not delete the file. It simply stops listening to it.

    The three clocks a WordPress update starts A horizontal timeline from 0 to 60 minutes after an update begins. The first bar, the maintenance notice from the .maintenance file, runs from 0 to 10 minutes. The second bar, the core update lock, runs from 0 to 15 minutes. The third bar, the background update lock, runs from 0 to 60 minutes. A note says that after 10 minutes visitors see the site again whether or not the update finished, so a site that comes back is not proof the update completed. One update, three clocks. What WordPress 7.1.2 starts when an update begins, and when each one stops counting. 0 10 min 15 min 60 min Maintenance notice .maintenance file then ignored Core update lock update in progress then released on the next try Background lock automatic updates no message; the next automatic run simply waits The site coming back is not proof the update finished. After 10 minutes WordPress serves pages again, whatever state the files were left in.

    Which Updates Put Your Site in Maintenance Mode, and Which Don’t

    Not every update writes the file, which is why briefly unavailable for scheduled maintenance can appear on one update and not the next. Read from the 7.1.2 upgrader classes, the rule is narrower than most guides assume: a manual update takes the site down only when it replaces code the site is running right now.

    UpdateWrites .maintenanceLock it takesIf the install fails
    Core, manualYes, alwaysCore lock, 15 minutesRe-run the update
    Core, automaticYes, alwaysCore lock and background lockAutomatic rollback attempt
    Plugin, manual, activeYesNoneRestored if the copy reports an error (6.3+)
    Plugin, manual, inactiveNoNoneRestored if the copy reports an error (6.3+)
    Plugin, automatic, active or inactiveYesBackground lock, 1 hourRestored on a reported error, plus a fatal-error check if it was active (6.6+)
    Theme, manual, active or parentYesNoneRestored if the copy reports an error (6.3+)
    Theme, manual, inactiveNoNoneRestored if the copy reports an error (6.3+)
    TranslationsNoBackground lock if automaticNot applicable
    The AHosting Maintenance Mode Map — which WordPress 7.1.2 updates show visitors the notice, and what each one does when it fails. On multisite, every manual plugin and theme update enables it.

    Why Update All Behaves Differently

    Clicking Update all, or ticking several plugins and choosing Update, runs them as one batch. WordPress writes .maintenance once, before the first plugin, and removes it after the last. Every plugin in the batch shares that one timestamp. If the batch runs past ten minutes, visitors start seeing the site again while files are still being replaced. Automatic updates work the other way: each item rewrites the file with a fresh timestamp, so each one gets its own ten minutes.

    How Long Has Briefly Unavailable for Scheduled Maintenance Been Showing?

    The time since the update started is the most useful thing you know, because it tells you which mechanism you are dealing with. Under ten minutes, WordPress is showing the notice deliberately. Over ten minutes, it is not, and deleting the file again will not help.

    Time since the update beganWhat is actually happeningWhat to checkWhat to do
    Under 10 minutesWordPress is honoring .maintenance; the update may still be runningNothing yetWait, or delete .maintenance if visitors cannot
    10 to 15 minutesThe notice has lifted; a core update lock may still be heldThe Updates screenWait for 15 minutes, then retry
    Over 15 minutes, same noticeNot WordPress’s timer: a stored copy, or a file it did not writeThe response status with curlPurge caches, or find the real file
    After it clearsThe interrupted update left work undonePlugins screen, Updates screen, error logRestore or reinstall what it was updating
    The AHosting Stuck-Notice Decoder — what the maintenance notice means at each point after an update starts, read against the WordPress 7.1.2 timers.

    Stuck Update Decoder

    Three questions about what you can see right now. The answer tells you which of the update’s leftovers you are looking at and what to do about it.

    —

    What is happening:

    Do this next:

    Read from the WordPress 7.1.2 source. It cannot see your server, so treat the answer as where to start, not as a diagnosis.

    Checking What the Server Actually Says

    Your browser is not a reliable witness here, because it shows whatever it last received. Ask the server directly with curl -sI https://example.com/, using your own address. The first line is the status, and the curl project’s own guide explains how to read it: a 5xx code means a problem on the server side. A 503 with Retry-After: 600 means something on the server is still producing the briefly unavailable for scheduled maintenance page right now. A 200 means the server is fine and the copy you are looking at is stored somewhere, in your browser or in a cache in front of the site. Purge that cache and reload in a private window.

    A Notice That Never Expires

    If the server still answers 503 well past ten minutes, open the .maintenance file you find. WordPress itself always writes a plain number. A file containing $upgrading = time(); instead was written by hand or by a tool, and it never expires, because time() is always now. Delete it. If there is no file, look for a maintenance or coming-soon plugin, and check that the folder you cleaned is the WordPress copy the domain actually serves.

    “Another Update Is Currently in Progress” Is a Different Lock

    The second message people meet after briefly unavailable for scheduled maintenance looks related and isn’t. Another update is currently in progress. comes from the core updater only, and it has nothing to do with .maintenance. Before a core update starts, WordPress inserts a row named core_updater.lock into its options table, holding the current time. While that row is younger than fifteen minutes, any second core update is refused with that message.

    Clearing the Core Update Lock

    The lock is written by WP_Upgrader::create_lock, which also explains why waiting works: once the row is older than its timeout, the next attempt deletes it and takes a fresh one. So the simplest fix is to wait until fifteen minutes have passed and retry. If you cannot wait, open phpMyAdmin from cPanel, find the options table, and delete the row whose option_name is core_updater.lock. With WP-CLI it is wp option delete core_updater.lock. Deleting .maintenance does not touch it, which is why the two messages can turn up one after the other.

    The Background Lock Nobody Sees

    Automatic updates take a second lock, auto_updater.lock, held for an hour. It never produces a message. If a background run is cut off, the next scheduled run inside that hour finds the lock and quietly does nothing. That is harmless once, but it is one more reason to read the Updates screen after any interrupted update rather than assuming the next automatic run will finish the job.

    What the Interrupted Update Left Behind, and How to Put It Back

    Once briefly unavailable for scheduled maintenance has lifted, by waiting or by deleting the file, the site loads whatever the update left on disk. Most of the time that is the finished update and nothing is wrong. When it is not, it shows up in one of three ways, and each has a specific fix.

    What you seeWhere to lookThe fix
    A plugin is missing or was deactivatedwp-content/upgrade-temp-backup/pluginsMove the folder back, then reactivate
    There has been a critical error on this websiteThe error log, then the plugin or core filesRestore the plugin, or reinstall the current core version
    The Updates screen still lists the updateDashboard, UpdatesRun it again, on its own
    Three leftovers of an interrupted WordPress update, and the repair for each.

    A Missing Plugin Is Usually in upgrade-temp-backup

    Since WordPress 6.3, the updater does not overwrite a plugin in place. As the 6.3 rollback announcement describes, it first moves the installed version into wp-content/upgrade-temp-backup/plugins/ under the plugin’s folder name, then copies in the new one. If the install fails, WordPress moves the old copy back. If the request is cut off between those two steps, the plugin folder is simply gone. The next time you open the Plugins screen, WordPress deactivates it with Plugin file does not exist. The old copy is still sitting in the backup folder. Move it back into wp-content/plugins with File Manager, reactivate it, and run the update again on its own. Do it the same day: a weekly cleanup task empties that folder.

    A Critical Error Means Old and New Files Are Mixed

    If the notice gives way to There has been a critical error on this website, the update stopped after replacing some files and before replacing others. For a plugin, restore it from the backup folder or reinstall it from its source. For core, open Dashboard, Updates and use the button to reinstall the current version, which copies every core file again. If wp-admin will not load at all, our white screen of death guide covers getting back in. While a plugin sits on its old version, look it up in the Wordfence vulnerability database to see whether that version has a known issue, which tells you how urgent the retry is.

    Why Updates Get Interrupted on Shared Hosting

    An update is an ordinary web request that happens to run for a long time. WordPress knows that and asks PHP for more room: the upgrader calls set_time_limit( 300 ) before each install, five minutes per package, and a background update of an active plugin gets ten for its fatal-error check. Most interruptions come from something that ends the request before the update can clean up after itself.

    The Safety Net Catches Errors, Not a Request That Dies

    The 6.3 rollback is scheduled only when the copy step returns an error that WordPress can see. It then runs in WordPress’s shutdown step, and the source comment says shutdown actions are “immune to PHP timeouts,” meaning the restore itself cannot be cut off by the clock once it has been scheduled. What the net cannot catch is the request dying in the middle of the copy. A timeout, a memory error or a killed process all end the request before WordPress learns the copy failed, so no restore is ever scheduled. .maintenance stays, any lock stays, and the old plugin stays in the backup folder.

    The error log tells those three apart. A timeout or a memory error is a PHP fatal error, and PHP writes it to the log with the file it was running. A killed process leaves nothing in PHP’s log at all, because the Linux signal manual is blunt about SIGKILL: it cannot be caught, blocked or ignored. An interrupted update with an empty error log points at a limit outside PHP.

    The Limits That Cause It

    On shared hosting, several ceilings sit outside PHP: memory for the whole account, the number of processes, and disk space and file count. A batch of large plugins can reach one of them halfway through. Resource limit errors are the visible version of that. The quieter one is space. During an update the old and new copies of a plugin exist side by side, so an account near its file-count limit can fail mid-copy even though it looked fine a minute earlier.

    How This Plays Out on AHosting Servers

    On our shared servers, LiteSpeed runs PHP through lsphp as your own cPanel user, and WordPress chooses its direct write method by itself, so an update never stalls waiting for an FTP login. That check is the other way the updater fails. On our WordPress plans, PHP’s own memory limit sits roughly eight to twelve times below the account’s memory ceiling. In practice that means an update that runs out of memory is stopped by PHP itself, long before the account limit, and the error log names the file it was loading. A failed update here is a diagnosable one: the log says what stopped it, and the old copy is waiting in the backup folder.

    How to Update Without Seeing Briefly Unavailable for Scheduled Maintenance Again

    You cannot make an update instantaneous, but you can keep it short and easy to trace if it fails. Four habits cover nearly every case of briefly unavailable for scheduled maintenance that outlives its ten minutes.

    1. Update active plugins in batches of five or six, not all at once. Each batch gets its own request and its own ten-minute window, and a failure points at a short list.
    2. Leave the Updates tab open until WordPress says it has finished. Closing it does not always stop the work on the server, but you lose the only screen that reports what went wrong.
    3. Check Disk Usage and File Usage on the cPanel home screen before a large update. An update briefly needs room for two copies of each plugin.
    4. Update WordPress core on its own, never in the same session as a long plugin batch, so the core lock and the plugin work cannot get in each other’s way.

    When to Bring Us In

    Most cases end with the steps above. On AHosting shared and WordPress hosting plans, PHP already runs as your own account, so updates write files directly. If the same update keeps stopping at the same point, or the plugin folder is gone and upgrade-temp-backup is empty, open a ticket and we will look at the error log with you. It usually shows whether PHP ran out of time or memory, or whether a file could not be written. That applies on our standard web hosting plans too.

    When a Server With More Room for Updates Makes Sense

    Updates that keep failing are usually about size, not about the server being broken. A WooCommerce store with dozens of extensions or a multisite network can carry more update work than one web request comfortably holds. On a VPS with full root access, you can run updates from the command line with WP-CLI, where no browser request is involved, and set the time and memory limits yourself.

    What does not justify a move is a single case of briefly unavailable for scheduled maintenance. A notice that clears in ten minutes and a plugin moved back from the backup folder is a repair, not a migration. Move when the size of every update is the problem, not one bad afternoon.

    Frequently Asked Questions: Briefly Unavailable for Scheduled Maintenance

    How do I remove a WordPress site from maintenance mode when it says briefly unavailable for scheduled maintenance?

    In practice you rarely have to. WordPress ignores its own .maintenance file ten minutes after the update that wrote it started, so the notice lifts by itself. If you cannot wait, open cPanel File Manager, turn on Show Hidden Files, and delete .maintenance from the folder that holds wp-config.php. Then go to Dashboard, Updates and Plugins, because the notice only told you an update stopped partway. Whatever it was updating may still be half done.

    How long does briefly unavailable for scheduled maintenance last before WordPress clears it in 2026?

    Typically ten minutes at most. The .maintenance file holds the time the update began, and WordPress 7.1.2 stops honoring it once ten minutes have passed. The page even tells browsers and crawlers to retry after 600 seconds. A normal update finishes in seconds and deletes the file itself. A notice that is still showing after ten minutes is not coming from that timer, so look for a cached copy or a hand made file instead.

    Deleting .maintenance vs waiting: which fixes briefly unavailable for scheduled maintenance faster?

    Specifically, deleting the file is faster, because it ends the notice at once, while waiting can take up to ten minutes. Neither one repairs anything. The file is only a sign that an update was interrupted, and the interrupted update is the real problem: a missing plugin folder, a half copied core, or a lock that still blocks the next attempt. Delete the file if visitors are waiting, then check the update itself either way.

    The .maintenance file vs the update lock: what is the difference between the two WordPress update errors?

    In other words, one stops visitors and the other stops updates. The .maintenance file sits in the site folder and shows visitors the maintenance notice for up to ten minutes. The update lock is a row in the WordPress options table that makes a second core update fail with Another update is currently in progress, for up to fifteen minutes. Deleting the file does nothing to the lock, which is why the two errors can appear one after the other.

    Why does my site still say briefly unavailable for scheduled maintenance after I deleted .maintenance?

    In fact WordPress is usually no longer the one saying it. Check what the server actually returns with curl or the browser network panel. If the response is a 200, you are looking at a stored copy from a cache in front of the site, so purge it. If it is still a 503 with a Retry After header, a .maintenance file still exists somewhere, often in a different copy of WordPress than the one you cleaned, or a maintenance plugin is active.

    A plugin vanished after briefly unavailable for scheduled maintenance: how do I get it back?

    Fortunately WordPress usually kept the old copy. Since version 6.3 it moves the installed version into wp-content/upgrade-temp-backup/plugins before copying the new one. If the update was cut off before WordPress could put it back, that copy is still there. Move the folder back into wp-content/plugins with File Manager, then reactivate the plugin, because WordPress deactivates any plugin whose files are missing. If the folder is empty, reinstall the plugin from its source.

    Does WordPress roll back a failed plugin update automatically in 2026?

    Indeed it does, when it sees the failure. Manual plugin and theme updates restore the previous version if the install step reports an error, and automatic plugin updates also load the home page afterward and restore the old version if it shows a fatal error. What it cannot catch is the request itself dying partway, from a timeout, a memory error or a killed process. Then no restore is scheduled, and the old copy stays in the backup folder for you to move back.

    Is it safe to click Update all on an AHosting WordPress plan in 2026?

    Overall yes for a few plugins, and smaller batches are safer for many. On AHosting plans PHP runs as your own account, so updates write files directly without asking for FTP details. The risk is time: Update all puts the site into maintenance mode once for the whole batch, and every plugin in it shares one request. Updating five or six at a time keeps each run short and makes a failure easy to trace to the plugin that caused it.

    Can AHosting support help when a site is stuck on briefly unavailable for scheduled maintenance?

    Above all, try the two minute fix first, because it is usually all you need: wait ten minutes or delete .maintenance, then finish the update. If the same update keeps stopping at the same point, or the plugin folder is gone and there is nothing to move back, open a ticket and we will look at the error log with you. The log usually shows whether PHP ran out of time or memory, or whether a file could not be written.

    Should I move to an AHosting VPS if WordPress updates keep failing in 2026?

    Ultimately not for one stuck update, which is a repair rather than a reason to migrate. A VPS makes sense when updates are large and frequent, such as a WooCommerce store with dozens of extensions or a multisite network, and you want to run them from the command line with WP-CLI instead of through a browser request. Root access lets you set the time and memory limits yourself, and it puts the rest of the server in your hands as well.

    October 2, 2026
  • WordPress Asking for FTP Credentials? It’s a File-Owner Check, Not a Password Problem

    WordPress Asking for FTP Credentials? It’s a File-Owner Check, Not a Password Problem

    • What WordPress Asking for FTP Credentials Actually Means
      • The Box, Word for Word
    • The Two Tests WordPress Runs Before It Asks for FTP
      • Test One: Can PHP Create a File in That Folder?
      • Test Two: Does the New File Have the Right Owner?
      • Where FS_METHOD Sits in That Order
    • Why the Same Check Quietly Turns Off Automatic Updates
      • The Silent Rows: Plugin and Theme Updates
    • How to Tell Which Test Failed Without Writing Code
      • Reading the Three Screens Together
    • What the Popular Fixes for WordPress Asking for FTP Credentials Actually Do
      • FS_METHOD Set to direct
      • Handing the Files to www-data
      • FTP_USER and FTP_PASS in wp-config.php
    • What You Can Fix Yourself on Shared Hosting
    • What Only Your Host Can Fix, and Why
      • How AHosting Servers Avoid the Mismatch
    • When FS_METHOD Set to direct Is the Right Answer
    • Frequently Asked Questions: WordPress Asking for FTP Credentials
      • Why is WordPress asking for FTP credentials when I try to install a plugin?
      • Is FS_METHOD direct a safe fix for WordPress asking for FTP credentials in 2026?
      • FS_METHOD direct vs fixing file ownership: which stops WordPress asking for FTP credentials?
      • FTP vs FTPS in the WordPress Connection Information box: is the password encrypted?
      • What causes WordPress asking for FTP credentials after moving a site to AHosting?
      • Why do I see WordPress asking for FTP credentials when Site Health says Writable?
      • Does WordPress store the FTP username and password typed into the Connection Information box?
      • Why does Site Health report background updates not working as expected in 2026?
      • Can AHosting support fix WordPress asking for FTP credentials on a CageFS account?
      • Should I move to an AHosting VPS to stop WordPress asking for FTP credentials in 2026?
    TL;DR

    WordPress asking for FTP credentials means one of two tests failed: it could not create a test file in the folder it wants to change, or that new file did not belong to the same user as WordPress’s own files. It is an ownership check, not a missing password. The popular FS_METHOD fix only switches the check off. The same failure quietly stops automatic updates, so find which test failed, fix that, and leave ownership to your host.

    What WordPress Asking for FTP Credentials Actually Means

    When you see WordPress asking for FTP credentials in the middle of a plugin install or an update, it is easy to read the box as a login you forgot to set up. It is not. WordPress did not lose a password. It ran a safety check on the folder it was about to change, the check failed, and FTP is the fallback it reaches for when it cannot prove that writing files directly is safe. Every useful fix starts from knowing which part of that check failed, and the most popular one skips the check instead of answering it.

    Listen: WordPress asks for FTP details when one of two file-ownership tests fails, and FS_METHOD only switches the check off. By Matt Chrust, Director of Business Development, AHosting.

    The Box, Word for Word

    The heading reads Connection Information. Underneath, WordPress 7.1.2, the current release on 30 September 2026, prints To perform the requested action, WordPress needs to access your web server. Please enter your FTP credentials to proceed. It then adds a sentence most readers skip: If you do not remember your credentials, you should contact your web host. Those words come from one function in wp-admin/includes/file.php, and that function prints the form only after a second function has already decided that writing directly is not an option. The form is a consequence. What this guide takes apart is the decision behind it.

    What WordPress checks before it asks for FTP credentials A decision flow in three steps from left to right. Step one: is the FS_METHOD constant defined in wp-config.php? If yes, WordPress uses it and skips the tests. Step two: can PHP create a test file in the folder WordPress is about to change? If no, the first test fails. Step three: is the new file owned by the same user as WordPress’s own core file? If no, the second test fails. Both tests passing leads to direct writes with no prompt. Either failure leads to the FTP fallback and the Connection Information box. A note below says the same failure also switches off automatic background updates. The FTP box is the answer to two tests. What WordPress 7.1.2 checks before any install or update, in order. 0. FS_METHOD defined? If wp-config.php sets it, WordPress uses it and skips both tests 1. Can PHP create a file? A test file in the folder it is about to change Fails: permissions or quota 2. Same owner? New file vs WordPress’s own core file Fails: ownership mismatch Both pass: direct writes No box. Installs, updates and auto-updates run as normal Either fails: FTP fallback The Connection Information box, and background updates stop Fix the test that failed, not the question it produced. FS_METHOD only reaches step 0. It turns the tests off; it does not make them pass.

    The Two Tests WordPress Runs Before It Asks for FTP

    Behind every case of WordPress asking for FTP credentials is one decision, made by get_filesystem_method, which returns one of four transports: direct, ssh2, ftpext or ftpsockets. Direct means PHP writes the files itself. The other three mean WordPress needs a login to a file-transfer service, and that is when the box appears. Direct is chosen only when two tests pass, one after the other.

    Test One: Can PHP Create a File in That Folder?

    WordPress creates a small file named temp-write-test- followed by a unique string in the folder it is about to change, wp-content by default. If PHP cannot open that file for writing, the first test fails and the second is never reached. Three things cause that: the folder’s permissions do not let the PHP user write, the folder belongs to someone else, or the account has no room for one more file. The last one surprises people, because nothing about the folder looks wrong.

    Test Two: Does the New File Have the Right Owner?

    If the file was created, WordPress asks PHP’s fileowner function for two numbers: the owner of the test file it just made, and the owner of file.php itself, one of WordPress’s own core files. Equal numbers mean PHP is creating files as the same user that owns WordPress. The source comment states the reasoning plainly: that is when it is “safe to modify & create new files via PHP.” Different numbers mean a write would leave files owned by the wrong user, so WordPress refuses and falls back to FTP. The test file is deleted either way.

    Where FS_METHOD Sits in That Order

    Before either test runs, WordPress checks whether wp-config.php defines FS_METHOD. If it does, that value wins and neither test runs. This is the whole reason define(‘FS_METHOD’, ‘direct’) makes the box disappear. It does not make the tests pass. It stops WordPress from asking the question. A value of ftpext left behind by a previous host does the opposite and forces the box on a server that does not need it.

    Why the Same Check Quietly Turns Off Automatic Updates

    Most guides treat WordPress asking for FTP credentials as an install problem and stop at the box, because the box is what the reader sees. The check behind it does more damage out of sight. WordPress’s automatic background updater runs the same filesystem test before every unattended update, and when it fails there is nobody there to type a password. So the update simply does not happen. Site Health notices: its Background updates item turns critical with the label Background updates are not working as expected and a note that reads, in part, Your site is performing updates over FTP due to file ownership. Talk to your hosting company.

    Update typeRuns the ownership testWhen the test fails
    Manual install or update from the dashboardYesThe Connection Information box
    Automatic core update that adds new filesYesSkipped; WordPress emails the admin instead
    Automatic core update that only changes existing filesRelaxed: writability onlyCan still run if the folder is writable
    Automatic plugin and theme updatesYesSkipped, with no email
    Automatic translation updatesYesSkipped, with no email
    The AHosting Background Update Map — what the filesystem check does to each kind of WordPress update, read from the 7.1.2 automatic updater. The quiet rows are the ones that matter.

    The Silent Rows: Plugin and Theme Updates

    The plugin row is the costly one. In its State of WordPress Security in 2026 report, Patchstack found that 91% of the new WordPress vulnerabilities it recorded in 2025 were in plugins and 9% in themes. A site whose files fail the ownership test stops receiving automatic plugin fixes and gets no email saying so. It is the same kind of silent failure as the WordPress.org connection warning that stops update checks, and it is found the same way: by reading Site Health rather than waiting for a symptom.

    How to Tell Which Test Failed Without Writing Code

    Diagnosing WordPress asking for FTP credentials needs no terminal. Three screens you already have answer it, and the order matters, because a constant in wp-config.php overrides everything the other two would tell you.

    1. Open wp-config.php in cPanel File Manager and search for FS_METHOD and FTP_. Any match is forcing the method before the tests run.
    2. In WordPress, go to Tools, then Site Health, then the Info tab, and open Filesystem Permissions. It lists the main WordPress directory, wp-content, uploads, plugins and themes as Writable or Not writable.
    3. On the cPanel home screen, read Disk Usage and File Usage together. Either one at its limit fails the first test even when every folder says Writable.

    Reading the Three Screens Together

    The detail that makes this work is what Site Health leaves out. Its Filesystem Permissions panel reports writability only; it never shows who owns anything. So a site that reads Writable everywhere, has room on the account and carries no constant, yet still shows the box, has narrowed the problem to the second test. A full account is the one trap in that logic, and the file-count limit on shared hosting is the version of it people miss.

    wp-config.phpSite Health: wp-contentcPanel usageTest that failedWho fixes it
    FS_METHOD or FTP_ linesAnyAnyNeither ran; a constant forced FTPYou
    CleanNot writableRoom leftTest 1: permissionsYou, or the host if the folder is not yours
    CleanWritableDisk or files fullTest 1: no room for the test fileYou
    CleanWritableRoom leftTest 2: ownership mismatchYour host
    The AHosting FTP Prompt Decoder — four screens you already have, read against the WordPress 7.1.2 filesystem check. The last row is the one only a host can fix.

    FTP Prompt Diagnoser

    Answer three questions from screens you already have: wp-config.php, Site Health and the cPanel home page. This tells you which of the two tests failed and who can fix it.

    —

    What is happening:

    Who can fix it:

    Do this next:

    Read from the WordPress 7.1.2 source. It cannot see your server, so treat the answer as where to start, not as a diagnosis.

    What the Popular Fixes for WordPress Asking for FTP Credentials Actually Do

    Search results for the box repeat three fixes almost word for word, and a fourth turns up in older forum threads. Read against the source, each one does something different from what it promises.

    Popular fixBox goes awayBackground updates returnWhat it costs
    FS_METHOD set to directYesOnly if the owners already matchedWrites files as whoever PHP runs as, and hides the mismatch
    Hand the files to www-data or apacheOnly where PHP runs as that userOnly on that kind of serverCreates the mismatch where PHP runs as your account
    FTP_USER and FTP_PASS in wp-config.phpYesYes, over FTPYour FTP password in plain text, in a file PHP reads constantly
    chmod 777 on wp-contentOnly if test 1 was the problemOnly if test 1 was the problemEvery process on the server can write there
    Correct the ownershipYesYesNothing, but on shared hosting it takes your host
    Five fixes for the FTP credentials box, read against the WordPress 7.1.2 filesystem check.

    FS_METHOD Set to direct

    It removes the box by deleting the question. If the owners already matched, the line was never needed. If they did not, WordPress now writes as the PHP user anyway: some writes fail with a less helpful error further along, and the rest create files the rightful owner may not be able to edit. Nothing about the mismatch changes, so the next person to read Site Health still finds it.

    Handing the Files to www-data

    That advice comes from servers where PHP runs as the web server’s own user, so giving that user the files makes the owners match. Plenty of shared hosts run PHP as each customer’s own account instead. There, handing the files to the web server user does not fix the mismatch. It creates one. On shared hosting you usually cannot run the command at all, which is a clue that the advice was written for a different kind of server.

    FTP_USER and FTP_PASS in wp-config.php

    This works, and it is the one to think hardest about. Your FTP password sits in plain text in a file PHP reads on every request, so any flaw that exposes that file exposes the password too. WordPress then logs in over FTP for every update. Pure-FTPd’s own TLS documentation spells out what encryption changes: with it, logins and passwords are no longer sent as cleartext. WordPress offers FTPS only when PHP’s ftp extension is loaded; its fallback client has no encryption at all.

    What You Can Fix Yourself on Shared Hosting

    Most cases of WordPress asking for FTP credentials end here. Three of the four outcomes in the decoder are yours to fix, and none of them needs more than cPanel. Work through them in this order, because each one can hide the next.

    1. Remove any FS_METHOD, FTP_USER, FTP_PASS or FTP_HOST line from wp-config.php, after saving a copy. Sites moved from another host often carry these for a server that needed them.
    2. Free room if Disk Usage or File Usage is at its limit: old backups, cache folders and unused plugins are the usual weight. The test file needs one free file slot.
    3. Put folder and file modes back to the defaults: 755 for folders and 644 for files, set with Change Permissions in File Manager. Never 777.

    Those two numbers are not arbitrary. Red Hat’s guide to file system permissions shows that the default umask on RHEL-family systems, which include CloudLinux, is 0022, and that is what produces 755 folders and 644 files when an owner creates them. If File Manager refuses to change a mode, the file is not yours, and that is the moment to stop. Our knowledge base article on permissions and ownership explains why no amount of chmod fixes a file someone else owns. The same distinction sits behind the Missing a temporary folder upload error, where the create step fails for reasons the error message never names.

    What Only Your Host Can Fix, and Why

    If the decoder lands on the last row, ownership has to change, and that is not a policy choice on the host’s part. The POSIX specification for chown allows only processes “with appropriate privileges” to change a file’s owner once restricted ownership is in effect, as it is on Linux. A hosting account does not have those privileges, and on our shared web hosting plans root access is not available, by design. So the one step that actually fixes a mismatch is the one step a customer cannot take.

    How AHosting Servers Avoid the Mismatch

    On our shared servers, LiteSpeed runs PHP through lsphp, and each PHP process runs as the site’s own cPanel user. Files you upload, install or restore belong to that same user, so both tests pass and WordPress chooses direct without a constant. We checked rather than assumed. Asked directly, the filesystem method returned direct on our live WordPress plan sites with no FS_METHOD defined. A scan of all 530 docroots on one shared server found exactly two files owned by anyone other than the account, both one-off manual uploads. In twelve months of AHosting support tickets, not one customer has reported WordPress asking for FTP credentials.

    On AHosting shared and WordPress hosting plans, PHP already runs as your own cPanel user, so a correctly owned site never sees this box. If it does appear, ownership is the one part of the fix you cannot do yourself, because only a privileged user can change a file’s owner. Open a ticket and we will look at it, before you edit wp-config.php.

    When FS_METHOD Set to direct Is the Right Answer

    There is a place for the constant: a server where you decide which user PHP runs as and who owns every file. On a VPS with full root access, a container, or a local development machine, you can make PHP and the files share one owner and then set FS_METHOD to direct knowing the check would have passed. That is a decision made with the facts in hand, not a way around them.

    What does not justify a move is WordPress asking for FTP credentials on its own. A mismatch on shared hosting is a ticket, not a migration. Move when you need that control repeatedly: custom services, your own deploy tools, or a PHP user you choose yourself.

    Frequently Asked Questions: WordPress Asking for FTP Credentials

    Why is WordPress asking for FTP credentials when I try to install a plugin?

    In practice it means WordPress could not prove that it is safe to write files directly. Before any install or update, it creates a small test file in the folder it is about to change, then compares the owner of that new file with the owner of its own core files. If the file cannot be created, or the two owners differ, WordPress falls back to FTP and asks you for a login. The box is the result of a failed ownership or write test, not a request for a missing password.

    Is FS_METHOD direct a safe fix for WordPress asking for FTP credentials in 2026?

    Typically it hides the problem rather than fixing it. Setting FS_METHOD to direct in wp-config.php makes WordPress skip both of its tests and write files as whatever user PHP runs as. If the tests were failing because the owners differ, the writes then either fail with a new error or create files owned by the wrong user. On a server where PHP runs as your own account and your files are yours, the tests already pass and the line is unnecessary. In WordPress 7.1.2 the logic is unchanged.

    FS_METHOD direct vs fixing file ownership: which stops WordPress asking for FTP credentials?

    Above all, fixing ownership, because only that removes the reason the box appeared. FS_METHOD direct tells WordPress to stop checking. Correcting the owner, so that the WordPress files belong to the same user PHP runs as, makes the check pass on its own, and it also brings back automatic background updates, which the same failed check had switched off. The constant leaves the mismatch in place for the next plugin, theme or core update to trip over.

    FTP vs FTPS in the WordPress Connection Information box: is the password encrypted?

    In particular, only if you choose FTPS and the server can actually offer it. WordPress shows the FTPS option only when the PHP ftp extension is loaded, because its fallback FTP client has no encryption at all. Plain FTP sends the login and password across the network as readable text. On AHosting servers the ftp and openssl extensions are both loaded, so FTPS is genuinely available, but a correctly owned site on our servers should never show the box in the first place.

    What causes WordPress asking for FTP credentials after moving a site to AHosting?

    Typically a line in wp-config.php that the previous host needed and this one does not. Some hosts run PHP as a shared web server user, so their sites carry FS_METHOD set to ftpext or FTP_USER and FTP_PASS lines to force updates over FTP. Copied across unchanged, those lines force the box on a server that does not need it. Remove them first. If the box stays, check for files a restore or copy left owned by another user, which only support can change.

    Why do I see WordPress asking for FTP credentials when Site Health says Writable?

    Specifically because Site Health reports only whether each folder is writable, never who owns the files inside it. WordPress passes its first test, creating a file, and fails the second, comparing owners. That combination points at ownership. One exception is worth ruling out first: an account at its disk or file limit can still show Writable, because the folder permissions are fine even though no new file fits. Check Disk Usage and File Usage in cPanel before you conclude it is ownership.

    Does WordPress store the FTP username and password typed into the Connection Information box?

    In fact only partly. WordPress saves the hostname and username in its options table so the form is prefilled next time, and it deliberately leaves out the password, the port and any SSH keys. The password is used for that one request and not kept. That is a real difference from typing the same password into wp-config.php as FTP_PASS, which stores it permanently as plain text in a file that PHP reads on every page load.

    Why does Site Health report background updates not working as expected in 2026?

    Notably, the same check that produces the FTP box is a common cause. Site Health runs the filesystem test itself, and when it fails the Background updates item turns critical with a note that the site is performing updates over FTP due to file ownership, telling you to talk to your hosting company. Automatic core updates then stop and WordPress emails the admin instead. Plugin and theme auto updates stop too, and those send no email at all.

    Can AHosting support fix WordPress asking for FTP credentials on a CageFS account?

    Indeed it can, and ownership is the part only support can do, because changing who owns a file needs privileges no customer account has. On AHosting shared and WordPress plans PHP already runs as your own cPanel user, so a correctly owned site never sees the box. When we scanned every docroot on one of our shared servers, only two files across 530 docroots belonged to anyone else. If you do see it, open a ticket and we will look at it, before you edit wp-config.php.

    Should I move to an AHosting VPS to stop WordPress asking for FTP credentials in 2026?

    Ultimately no, not for this reason alone. WordPress asking for FTP credentials is caused by a file ownership mismatch, and on shared hosting that is a ticket, not a migration. A VPS makes sense when you need control you will use again and again: choosing which user PHP runs as, owning the whole file tree with root access, and running your own deploy tools. On a VPS you can also set FS_METHOD to direct safely, because you decide who the PHP user is.

    October 1, 2026
1 2 3 … 13
Next Page→
Ahosting Logo

Hosting

  • WordPress Hosting
  • Web Hosting
  • FFmpeg Hosting
  • WooCommerce Hosting
  • Reseller Hosting
  • VPS Hosting
  • Dedicated Server

Domain

  • Register a Domain
  • Domain Transfer
  • Premium SSL Certificate

Support

  • Knowledge Base
  • Abuse Report
  • Submit A Ticket

Company

  • Compare Hosts
  • About Us
  • Datacenter
  • Contact Us
  • Blog
  • Sitemap

Legal

  • Privacy Policy
  • Terms of Service
  • Acceptable Use Policy
  • Service Level Agreement
  • Resource Abuse Policy
  • Hosting
    • WordPress Hosting
    • Web Hosting
    • FFMpeg Hosting
    • WooCommerce Hosting
    • Reseller Hosting
    • VPS Hosting
    • Dedicated Server
  • Domain
    • Register a Domain
    • Domain Transfer
    • Premium SSL Certificate
  • Support
    • Knowledge Base
    • Abuse Report
    • Submit A Ticket
  • Company
    • About Us
    • Datacenter
    • Contact Us
    • Blog
    • Sitemap
  • Legal
    • Privacy Policy
    • Terms of Service
    • Acceptable Use Policy
    • Service Level Agreement
    • Resource Abuse Policy

Copyright © 2026 All Rights Reserved

Ahosting, Inc. BBB Accredited Business, A+ rating
Facebook X/Twitter Instagram LinkedIn YouTube