GUIDE · 02 · VERIFIED 2026-10allwpcare.com/guides/find-and-undo-changed-wordpress-settings/
Guides / Troubleshooting / find-and-undo-changed-wordpress-settings

Someone Changed My WordPress Settings: Find and Undo It

How to find out what changed in WordPress settings and put it back: backups, host snapshots, activity logs, and a wp_options diff you can run yourself.

Last verified Oct 2026Tested with WordPress 7.111 min read

WordPress does not record who changed a setting or when, so you find the change by comparing today's settings with an older copy: a backup, a host snapshot, or a saved export. The fix is to put back only the options that differ, not the whole database.

If you have no older copy, you can still work out a lot from what the site tells you. This guide covers both cases, in the order that tends to save time.

First, stop and write down what you see#

Before you change anything, make a record of the current state. A fix that goes wrong should not cost you your evidence.

  1. Note the symptom. Which page or setting looks wrong, and what did it look like before?
  2. Take a backup of the site as it is now. Use your host's tool or a database export (wp db export ~/before-fix.sql, which writes to your home folder, not the WordPress folder). It is the copy you compare against, and the copy you fall back on if your fix makes things worse.
  3. Save the current options to a file outside the WordPress folder. If you have WP-CLI:
    Terminal
    wp option list --orderby=option_name --unserialize --format=json > ~/options-now.json
    Plain wp option list leaves transients out by default (tested on WP-CLI 2.12). The --transients flag does the opposite: it lists only the transients.
  4. Do not edit anything yet. Edits overwrite the evidence.

Keep options-now.json private. It can contain keys and passwords. Never leave exports inside the WordPress folder: anything there can be fetched by URL. That is why the commands write to your home folder (~/), and why you should delete the files when you are finished.

What WordPress can and cannot tell you#

Core has no change history for settings. The wp_options table has four columns: option_id, option_name, option_value and autoload. None of them is a date or a user.

Two small clues exist:

  • Order of creation. Each new option gets a higher option_id. Sorting by it shows options added recently, which is useful when a plugin created new rows. It does not show changed options, because a changed option keeps its ID.
  • Related content dates. Some changes leave a trace elsewhere: a post's modified date, a plugin's own log, or a new user's registration date.

To see the newest options on your site:

Terminal
wp option list --orderby=option_id --order=desc --fields=option_name --format=csv | tail -n +2 | head -20

The tail -n +2 drops the CSV header line. Many of the newest rows are plugin housekeeping, for example Action Scheduler or SMTP notification options, so treat this as a lead, not a verdict.

Users are another thing you can check. If an unexpected administrator exists, that matters more than any setting:

Terminal
wp user list --role=administrator --fields=ID,user_login,user_registered --format=csv

Look for accounts you do not recognise, or ones created around the time the trouble began. If you find one, treat it as a security problem first, but take the backup from the first section before you touch anything.

Then act in this order:

  1. Do not delete the account yet. Deleting a user also deletes their posts unless you reassign the content, and the account is evidence. Demote it to Subscriber, or reset its password, instead. When you do delete it later, choose to reassign the content to another user.
  2. Reset the password of every administrator, and rotate the secret keys and salts in wp-config.php. That logs everyone out, including anyone using a stolen session.
  3. Look for things you did not install. Check the plugin and theme lists for unknown entries, and look in wp-content/plugins, wp-content/themes and wp-content/uploads for unfamiliar folders or .php files (there should be almost no PHP in uploads).
  4. If you think the site is compromised, stop here and bring in your host or a security professional. Cleaning a hacked site by hand is easy to get wrong. See the prevention section below for how to reduce the chance of a repeat.

Find the last good copy#

You need an older version of the settings to compare with. Look in these places, from easiest to hardest:

  • A saved export. If you or a developer saved settings from before, that is the best source, because it holds only settings.
  • Host snapshots. Many hosts keep daily or on-demand snapshots. Where they live, how long they are kept, and what they include differ by host. Check your host's dashboard and its documentation. Some snapshots cover files and the database together.
  • Backup plugin archives. If a plugin has been taking backups, its archive can usually be downloaded.
  • Database dumps. A .sql file you or your host made earlier.
  • A staging copy. If you have a staging site made before the change, it carries the old values. Staging also holds environment-specific values, so read carefully.

Whatever you pick, restore the old copy to a place where it cannot hurt: a local site, a staging site, or a scratch database. Do not restore it over the live site just to look at it.

Four rows. Your own saved settings copy gives old and new side by side. A host backup restored to a scratch copy gives old values. An activity log shows who and when but usually not the old value. With nothing at all, core keeps only the current value.
What you can compare with, from most to least useful.

Compare the old and new settings#

Once the old copy is running somewhere, export its options the same way as the current ones:

Terminal (on the old copy)
wp option list --orderby=option_name --unserialize --format=json > ~/options-old.json

Both files now have the same shape, sorted by name, with arrays decoded. Compare them:

Terminal
diff \  <(jq -r '.[] | "\(.option_name)=\(.option_value)"' ~/options-old.json) \  <(jq -r '.[] | "\(.option_name)=\(.option_value)"' ~/options-now.json)

Lines starting < are the old version and lines starting > are the current one. An option present only on one side was added or removed. A name with different values on each side was changed.

Three rows. A line starting with a less-than sign is the old copy. A line starting with a greater-than sign is the current site. A name on one side only was added or removed.
How to read each line of the diff.

I tested this routine on a site by changing the tagline. The output was exactly one pair of lines: blogdescription= for the old, and blogdescription=x for the new. A real comparison is noisier, and you will see lines that do not matter.

Ignore the noise#

A raw diff will contain lines you can skip safely:

  • Anything beginning _transient_, _site_transient_, or _transient_timeout_. These are caches. wp option list leaves them out by default.
  • cron. The scheduled-task list changes constantly.
  • recently_activated, fresh_site, and counters or "last run" timestamps that plugins keep.
  • Values ending in _last_checked or containing a date that moves.
  • _db_version options if a plugin or core updated in between.

If the noise is overwhelming, filter it out up front. WP-CLI's --exclude takes only one pattern, so use jq to drop several names:

Terminal
wp option list --orderby=option_name --unserialize --format=json \  | jq 'map(select(.option_name | IN("cron", "recently_activated", "fresh_site") | not))' > ~/options-now.json

Run the same filter on the old copy so both files match.

What is left are options that something or somebody set on purpose, or a plugin changed as part of its work.

Read the changes like a human#

Option names are not always friendly. Match them to the screens you know:

  • blogname, blogdescription, timezone_string, date_format, default_role: Settings → General
  • default_post_format, default_category: Settings → Writing
  • show_on_front, page_on_front, posts_per_page, blog_public: Settings → Reading
  • default_comment_status, comment_moderation, comments_notify: Settings → Discussion
  • permalink_structure: Settings → Permalinks
  • wpseo_*, rank-math-options-*, woocommerce_*: plugin screens from Yoast SEO, Rank Math and WooCommerce. Rank Math's settings use hyphens; its rank_math_* rows are mostly modules and version housekeeping
  • theme_mods_ followed by a theme name: Appearance and the Customizer

To read a single option by itself, wp option get NAME works. In the browser, /wp-admin/options.php (the hidden All Settings page, not linked from the menu) shows plain values, though arrays appear as SERIALIZED DATA.

Two changes deserve extra attention when they appear:

  • blog_public set to 0 means "Discourage search engines". If your traffic vanished, check this first.
  • default_role set to administrator would make every new registration an administrator, if Anyone can register is ticked in Settings → General (the users_can_register option is 1). That is dangerous. Check both options, fix them at once, and look at your user list. With registration closed, the role matters far less, but it is still wrong.

Put it back#

Restore the specific options, not the whole database. For each changed option you want to revert, write the old value from the old copy:

Terminal
wp option get blogdescription --format=json   # run on the old copywp option update blogdescription "Old tagline here"   # run on the live site

For arrays, export from the old copy as JSON and import with the same flag:

Terminal
wp option update wpseo_titles --format=json < ~/wpseo_titles.json

Leave out the flag and the array is stored as text. That is the most common way a revert makes things worse.

If you only have the admin screens, set each value by hand from the old copy using the normal settings pages. It is slower but it validates what you type.

Why not restore the whole backup?#

It is tempting, and sometimes right. But a full restore returns the whole site to the backup's date. Every order, comment, form entry and edit made since is lost.

A full restore makes sense when:

  • The site is badly broken and you cannot tell what is wrong.
  • The backup is recent enough that nothing of value happened since.
  • You were hacked, and you restore to before the compromise, then patch and change every password.

Otherwise, revert the specific options.

Ask your host#

Hosts have information you cannot see. Ask:

  • Does the access log show who logged in to the admin around the time of the change? Logs can also show requests to admin-ajax.php and options.php.
  • Are there snapshots from before the change, and how can I restore them to a separate location?
  • Did any automatic update run?

What a host keeps, and for how long, varies. Ask early, because logs are often rotated within days or weeks.

Activity logs#

An activity-log plugin records who did what and when, going forward. Many record logins, settings changes, plugin and theme actions, and user changes. They cannot tell you about changes made before you installed them, so install one before you need it. Choose one that records the username and the old and new values, and check where it stores its data and how long it keeps it.

Updates and plugins that change settings#

Not every change is a person. Common non-human causes:

  • A plugin update migrated its settings. Some updates rewrite their options into a new shape or add defaults.
  • A plugin deactivation or deletion. Some plugins remove their options on uninstall.
  • A setup wizard. Plugins like WooCommerce and SEO plugins run wizards that write many options at once.
  • A staging push. Someone pushed a copy from staging, and brought the staging values with it.
  • Auto-updates. If auto-updates are on, a change could appear without anyone logging in.

The diff shows the new values but not the cause. Check the plugin's changelog for the version that updated, and the "last updated" date shown for it on the Plugins screen. Your host's access and error logs, or an activity-log plugin, can show what ran and when. Dashboard → Updates lists only pending updates, and Tools → Site Health shows only the current state. Neither keeps a history.

Prevent the next one#

  1. Take a settings snapshot regularly. A dated JSON file of your options is cheap. Keep it somewhere private and outside the WordPress folder, since it can contain secrets.
  2. Give people the lowest role that does the job. Editors cannot change settings. Administrators can.
  3. Delete unused administrator accounts, and use unique passwords with two-factor authentication.
  4. Install an activity log and keep its data for a useful length of time.
  5. Disable the file editor for plugins and themes, so a stolen login cannot edit code from the admin. Keep a copy of wp-config.php first, then add define( 'DISALLOW_FILE_EDIT', true ); above the line that says require_once ABSPATH . 'wp-settings.php';. A define placed after that line is too late, because WordPress has already loaded.
  6. Test changes on staging first. Then move only the options that you changed. See the staging-to-live guide.

If you saved a snapshot with WellTend Snapshots before the change, you do not need the shell commands. Open the snapshot and it lists what is different from your site now. I saved a snapshot, then changed two settings: one in General and one in Reading. The screen reported "2 settings are different", one under General settings and one under Reading settings. "2 secrets hidden" means two values that look like passwords or keys were found. The plugin does not show them and never restores them, so your site keeps its own. Nothing is restored until you tick settings and confirm.

WellTend Snapshots, Snapshot 1 named Before the change, compared with Your site now. It says 2 settings are different and 2 secrets hidden. General settings and Reading settings each show 1 difference. Buttons: Restore everything in this snapshot and Restore selected.
WellTend Snapshots 0.5.0: a saved snapshot against the site as it is now.
Put a setting back, with an undo.

Restore one area of settings or a whole snapshot. A pre-restore snapshot is saved first, so a wrong click is reversible.

dry-run preview   automatic undo  
Get notified

A short checklist#

If you are working through this under pressure, go slowly on the first three steps. They are what keep a small problem small.

Related: export and import WordPress settings.

FAQ

Does WordPress keep a history of settings changes?

No. Core stores only the current value of each option. The wp_options table has no modified date and no record of who changed a value. To get history you need a backup, a host snapshot, or an activity-log plugin that was already running when the change happened.

Can I find out who changed a setting?

Only if something recorded it. An activity-log plugin or a server access log can show which account made the request. Without one, you can see what is different now, but not who did it.

Is it safe to restore an old database backup?

Restoring a whole backup also rolls back every post, order and comment made since. For a settings-only mistake, copy back just the affected options instead, taking a fresh backup first.

What if the settings changed because of a plugin update?

Updates can migrate or reset settings. Compare the option before and after, check the plugin's changelog, and restore the old value of the specific option if the plugin allows it.

How do I stop it happening again?

Give each person the lowest role they need, remove unused administrator accounts, turn on an activity log, and keep a recent snapshot of your settings so there is always something to compare against.

Sources

  1. WP-CLI: wp option list · --orderby, --unserialize. --transients lists only transients; the default leaves them out (tested on WP-CLI 2.12)
  2. WP-CLI: wp option · get and update, --format=json
  3. WP-CLI: wp db export · Taking a database dump
  4. Core: wp_options table definition (schema.php) · The CREATE TABLE $wpdb->options block: four columns, no modified date
  5. Core: get_option()
  6. Core: update_option() · Writes the new value over the old one
  7. Advanced administration: editing wp-config.php · DISALLOW_FILE_EDIT turns off the file editor
Newsletter

One email when something breaks or changes.

New plugins and re-tested guides, about twice a month. Never a sales pitch.