wp-config.php » WP_SECRETS_KEY in WordPress 7.2: Add It to wp-config.php

WP_SECRETS_KEY in WordPress 7.2: Add It to wp-config.php

WordPress 7.2 adds a Secrets API, and it needs a new constant in wp-config.php: WP_SECRETS_KEY. New installs get it from the installer together with the salts. Existing sites do not, so every site that updates to 7.2 has to add it by hand.

If you skip it, nothing breaks on the front end. But any plugin that uses the new API cannot store or read its credentials, and Site Health flags it under Security. As of 2026-11-12, 7.2 is at Beta 5 and the final release is scheduled for December 8, 2026 (per the Beta 5 announcement), so now is a good time to prepare your sites.


The Secrets API gives plugins two main functions, wp_set_secret() and wp_get_secret(), to store things like API keys and OAuth client secrets encrypted instead of as plain options. The details are in the Secrets API dev note published on November 11.

Encryption uses libsodium. Each secret is encrypted with keys derived from a random root key, and that root key is stored encrypted with WP_SECRETS_KEY from wp-config.php.

Early betas fell back to a key built from LOGGED_IN_KEY and LOGGED_IN_SALT when no key was set. That fallback is gone. Without a usable WP_SECRETS_KEY the API stores nothing, and every write and every read of a stored secret returns a secret_key_unavailable error.

“Usable” matters here. An empty string, the placeholder from wp-config-sample.php, or a value copied from one of your authentication keys or salts does not count.


You are about to edit the file that holds your database credentials. Make a copy before you touch it.

cp wp-config.php wp-config.php.bak

No output means the copy worked. If you only have FTP or a file manager, download the file to your computer instead.

The dev note asks for a base64-encoded random 32-byte key. Generate it with PHP on the command line:

php -r 'echo base64_encode( random_bytes( 32 ) ), "\n";'

You get one line of 44 characters ending in =. Run it once per site, because every site should get its own key.

No shell access? Go to Tools > Site Health on a 7.2 site. According to the dev note, Site Health generates a line for you to copy into wp-config.php.

Open wp-config.php and paste the line right below the block of authentication keys and salts, above the /* That's all, stop editing! */ comment:

define( 'WP_SECRETS_KEY', 'paste-your-generated-key-here' );
wp secrets key wordpress 7 2 wp config 1 - WP_SECRETS_KEY in WordPress 7.2: Add It to wp-config.php
Where it goes in wp-config.php: above the “That’s all, stop editing!” line

With WP-CLI you can do the same without opening the file. Run it from the WordPress root:

wp config set WP_SECRETS_KEY "$(php -r 'echo base64_encode( random_bytes( 32 ) );')" --type=constant

WP-CLI should answer with a Success line. If it complains that it cannot find wp-config.php, you are not in the WordPress directory, so add --path=/path/to/wordpress.

💡 Do not reuse a value from your salts here, even if you just made fresh ones with a salts generator. The API does not accept keys copied from them.

On a 7.2 site, open Tools > Site Health. The dev note lists three new tests under Security: Secrets API key source, Secrets API: undecryptable secrets and Secrets API: credentials pending rotation. The key source test should no longer show up as a recommended improvement.

From the command line, ask the API directly:

wp eval 'var_dump( wp_is_secrets_api_available() );'

You want bool(true). If you get bool(false), the key is missing, not usable, or cannot decrypt a root key that was already stored. The Info tab in Site Health also has a Secrets API section with the provider, keyring, key source and number of stored secrets.

See also  Loopback Request Failed: Fix WP-Cron Status Code 0 in WordPress

This is the part that will bite people. Salts can be rotated at any time, and the worst that happens is that everyone gets logged out.

WP_SECRETS_KEY is not like that. The dev note is clear: once secrets are stored, changing or removing the key makes all of them unreadable until the old value comes back. A few habits I would adopt now:

  • Store the key in your password manager, next to the database password. A backup of wp-config.php is not enough if that backup lives on the same server.
  • When you clone production to staging, copy the key too. The encrypted root key travels with the database, so a staging site with a different key cannot read the secrets.
  • Do not let a hardening plugin or a script that regenerates salts touch this line.
  • If you build wp-config.php with your own deploy script, add the key there. The dev note says WP-CLI’s wp config create is being updated to add it as well.

If you keep wp-config.php outside the web root, as I describe in Move wp-config.php outside the web root directory, nothing changes. The constant only has to be defined before WordPress loads.


Secrets stored on an earlier beta without WP_SECRETS_KEY were encrypted under the old salt-based fallback. After updating, Site Health reports them as undecryptable, but they are still in the database. Do not change your salts until you finish these steps, because the old key is built from them.

First add both the new key and the old one, below the salts:

define( 'WP_SECRETS_KEY', 'your-new-generated-key' );
define( 'WP_SECRETS_KEY_PREVIOUS', LOGGED_IN_KEY . LOGGED_IN_SALT );
wp secrets key wordpress 7 2 wp config 2 - WP_SECRETS_KEY in WordPress 7.2: Add It to wp-config.php
Where it goes in wp-config.php: above the “That’s all, stop editing!” line

Then re-encrypt the root key with the new key. This is the command from the dev note:

wp eval '$r = ( new WP_Secrets_Key_Manager() )->rotate_site_key( new WP_Secrets_Config_Key_Provider( true ), new WP_Secrets_Config_Key_Provider() ); echo is_wp_error( $r ) ? $r->get_error_message() : "Done.";'

It prints Done. on success, or the error message if something failed. When it is done, remove the WP_SECRETS_KEY_PREVIOUS line. On multisite one run covers the whole network, and no stored secret is rewritten.

💡 If you already added WP_SECRETS_KEY earlier, keep it as it is and add only the WP_SECRETS_KEY_PREVIOUS line.

The same approach works whenever you need to replace the key later: put the old value in WP_SECRETS_KEY_PREVIOUS, set the new one, run the rotation, then remove the old line.


If you maintain a plugin that keeps an API key in an option, do not assume the API is ready on every site. Plenty of sites will update to 7.2 without the key, at least at first. Check first and keep your old storage as the fallback:

if ( function_exists( 'wp_is_secrets_api_available' ) && wp_is_secrets_api_available() ) {
	// Move the credential with wp_set_secret().
} else {
	// Keep the existing option storage.
}

The function_exists() check is my addition for sites still on 7.1. Also note that wp_get_secret() returns null only when a secret was never stored. A WP_Error means it exists but cannot be read right now, for example because the key is missing, so do not ask the user for a new credential in that case.

This is not the only wp-config.php cleanup in the 7.2 cycle. If you have not done it yet, also read about the removal of load-scripts.php, which leaves dead constants behind.

TL;DR: before or right after updating to WordPress 7.2, generate a key with php -r 'echo base64_encode( random_bytes( 32 ) );', add define( 'WP_SECRETS_KEY', '...' ); below the salts, confirm it in Site Health, and save the key somewhere safe. Never change it once secrets are stored.

Was this post helpful?

Leave a Comment

I enjoy constructive responses and professional comments to my posts, and invite anyone to comment or link to my site.

Recommended