Disable WordPress Automatic Updates but Keep Security Fixes

Automatic updates can break a working WordPress site, and you usually find out when a client reports it. Disabling WordPress automatic updates completely has its own risk: a site that misses a security release is an easy target. This snippet stops the updates that tend to break things, major core versions, plugins and themes, and keeps minor core releases, which are the security and maintenance fixes.

The snippet

<?php
/**
 * No automatic major core, plugin or theme updates.
 * Minor core releases (security and maintenance fixes) still install automatically.
 */
add_filter( 'allow_major_auto_core_updates', '__return_false', 100 );
add_filter( 'allow_dev_auto_core_updates', '__return_false', 100 );
add_filter( 'auto_update_plugin', '__return_false', 100 );
add_filter( 'auto_update_theme', '__return_false', 100 );

// To stop security releases too, uncomment the next line (not recommended):
// add_filter( 'allow_minor_auto_core_updates', '__return_false', 100 );

How it works

  • allow_major_auto_core_updates decides whether WordPress may move to a new major version on its own (for example 6.8 to 6.9). Returning false keeps the site on its branch until you update from Dashboard → Updates.
  • allow_dev_auto_core_updates does the same for beta, RC and nightly builds on development installs.
  • auto_update_plugin and auto_update_theme are asked for every plugin and theme before a background update. Returning false overrides the “Enable auto-updates” links, and the Plugins and Themes screens show auto-updates as disabled.
  • Minor releases (6.8.1 to 6.8.2) are decided by allow_minor_auto_core_updates, which the snippet leaves alone.
  • Priority 100 wins over plugins that switch updates back on at the default priority.

The older One-Click Import version returned false from auto_update_core, which blocked security releases as well and left plugin and theme auto-updates untouched.

Add it with Scripts Organizer

In Scripts Organizer go to Code Blocks → Add New and give the block a name. Set Trigger location to Everywhere, tick PHP under Script location, paste the code into the PHP editor and publish. Leave Action/Hook empty. Do not use Admin only: background updates run during WP-Cron, which is triggered by front-end visits and wp-cron.php, not by wp-admin, so Admin only code would not be loaded when the updater makes its decision.

An mu-plugin is an even safer home for this one, because it can’t be switched off by accident.

The same code also works unchanged in a small plugin or an mu-plugin.

Customise it

  • Allow plugin auto-updates again: delete the auto_update_plugin line.
  • Allow one plugin only: replace __return_false for auto_update_plugin with a function that returns true when $item->slug is that plugin’s slug and false otherwise.
  • Stop security releases too: uncomment the last line. Only do that on sites you update by hand every week.

To hear about security releases by email, see WordPress Security Updates Email Alert Without a Plugin. To hide update checks and notices altogether, see Disable WordPress Core, Plugins and Themes updates and Admin Notices.

Gotchas

  • This only controls automatic updates. Manual updates still work.
  • AUTOMATIC_UPDATER_DISABLED in wp-config.php switches off every automatic update, security releases included, before these filters are asked. Check wp-config.php if minor releases stop arriving.
  • Managed hosts often run their own updater outside WordPress; check the host’s control panel as well.

In the Scripts Organizer library Import it with one click from Scripts Organizer.

// newsletter

Three tested WordPress snippets a week

Blocks, security, performance, Tailwind, PHP and React. Copy, paste, ship. You’ll also get DPlugins product updates. No spam, and you can unsubscribe anytime.

// newsletter

Three tested WordPress snippets a week

Blocks, security, performance, Tailwind, PHP and React. Copy, paste, ship. You'll also get DPlugins product updates. No spam, and you can unsubscribe anytime.