The server metadata private key is not valid. Unable to validate metadata private key (id: <UUID>) cleartext data

Checklist
I have read intro post: https://community.passbolt.com/t/about-the-installation-issues-category/12
I have read the tutorials, help and searched for similar issues
I provide relevant information about my server (component names and versions, etc.)
I provide a copy of my logs and healthcheck
I describe the steps I have taken to trouble shoot the problem
I describe the steps on how to reproduce the issue

Hello,

Since upgrading our test instance to Passbolt CE 5.4.0 (currently on 5.5.0.) I’m getting this error message from the healthcheck:

 [FAIL] The server metadata private key is not valid. Unable to validate metadata private key (id: <UUID>) cleartext data.

I haven’t found any relevant info searching Passbolt’s github and forum or the web in general.

I tried running passbolt commands like “cake passbolt cleanup”, “cake cache clear_all”, “cake passbolt datacheck” but nothing chenged.

The instance seems to be working fine but I’m afreaid to update our production instance in case something breaks.

Server info:

  • Alma 8.10 fully updated
  • Nginx 1.14.1
  • MySQL 8.0.41
  • PHP 8.2.29
  • Passbolt CE 5.5.0
  • Metadata key policy: “Allow the use of personal keys”
  • Supported metadata types: “Enable encrypted metadata” and “Enable legacy cleartext metadata” (default: encrypted)
  • Migration status: Done (Resources: All migrated)
  • Allow content types: “Encrypted metadata” (6604 + 97 resources) and “Legacy cleartext metadata” (0 resources)

Healthcheck:

[root@passbolt.vps ~] # sudo -H -u nginx bash -c "/usr/share/php/passbolt/bin/cake passbolt healthcheck"

     ____                  __          ____
    / __ \____  _____ ____/ /_  ____  / / /_
   / /_/ / __ `/ ___/ ___/ __ \/ __ \/ / __/
  / ____/ /_/ (__  |__  ) /_/ / /_/ / / /
 /_/    \__,_/____/____/_.___/\____/_/\__/

 Open source password manager for teams
-------------------------------------------------------------------------------
 Healthcheck shell
 If you want to have more information about the different checks, please take a look at the documentation: https://www.passbolt.com/docs/admin/server-maintenance/passbolt-api-status/
-------------------------------------------------------------------------------

 Environment

 [INFO] Linux passbolt.vps 4.18.0-553.75.1.el8_10.x86_64 #1 SMP Mon Sep 15 08:42:43 EDT 2025 x86_64 x86_64 x86_64 GNU/Linux
 [PASS] PHP version 8.2.29.
 [PASS] PHP version is 8.2 or above.
 [PASS] 64-bit architecture system detected.
 [INFO] gpg (GnuPG) 2.2.20 / libgcrypt 1.8.5
 [PASS] PCRE compiled with unicode support.
 [PASS] Mbstring extension is installed.
 [PASS] Intl extension is installed.
 [PASS] GD or Imagick extension is installed.
 [PASS] The temporary directory and its content are writable and not executable.
 [PASS] The logs directory /var/log/passbolt/ and its content are writable.
 [WARN] System clock is synchronized but NTP service is inactive.
 [HELP] See `timedatectl | grep -i -A 1 clock`. More information: https://www.passbolt.com/docs/hosting/configure/ntp/

 Config files

 [PASS] The application config file is present
 [PASS] The passbolt config file is present

 Core config

 [PASS] Cache is working.
 [PASS] Debug mode is off.
 [PASS] Unique value set for security.salt
 [PASS] Full base url is set to https://passbolt-test.domain.tld
 [PASS] App.fullBaseUrl validation OK.
 [PASS] /healthcheck/status is reachable.

 SSL Certificate

 [PASS] SSL peer certificate validates.
 [PASS] Hostname is matching in SSL certificate.
 [PASS] Not using a self-signed certificate.

 SMTP settings

 [PASS] The SMTP Settings plugin is enabled.
 [PASS] SMTP Settings coherent. You may send a test email to validate them.
 [PASS] The SMTP Settings source is: database.
 [WARN] The SMTP Settings plugin endpoints are enabled.
 [HELP] It is recommended to disable the plugin endpoints.
 [HELP] Set the PASSBOLT_SECURITY_SMTP_SETTINGS_ENDPOINTS_DISABLED environment variable to true.
 [HELP] Or set passbolt.security.smtpSettings.endpointsDisabled to true in /etc/passbolt/passbolt.php.
 [PASS] No custom SSL configuration for SMTP server.

 JWT Authentication

 [PASS] The JWT Authentication plugin is enabled.
 [PASS] The /etc/passbolt/jwt/ directory is not writable.
 [PASS] A valid JWT key pair was found.

 GPG Configuration

 [PASS] PHP GPG Module is installed and loaded.
 [PASS] The environment variable GNUPGHOME is set to /var/lib/passbolt/.gnupg.
 [PASS] The directory /var/lib/passbolt/.gnupg containing the keyring is writable by the webserver user.
 [PASS] The server OpenPGP key is not the default one.
 [PASS] The public key file is defined in /etc/passbolt/passbolt.php and readable.
 [PASS] The private key file is defined in /etc/passbolt/passbolt.php and readable.
 [PASS] The server key fingerprint matches the one defined in /etc/passbolt/passbolt.php.
 [PASS] The server public key defined in the /etc/passbolt/passbolt.php (or environment variables) is in the keyring.
 [PASS] There is a valid email id defined for the server key.
 [PASS] The public key can be used to encrypt a message.
 [PASS] The private key can be used to sign a message.
 [PASS] The public and private keys can be used to encrypt and sign a message.
 [PASS] The private key can be used to decrypt a message.
 [PASS] The private key can be used to decrypt and verify a message.
 [PASS] The public key can be used to verify a signature.
 [PASS] The server public key format is Gopengpg compatible.
 [PASS] The server private key format is Gopengpg compatible.

 Application configuration

 [PASS] Using latest passbolt version (5.5.0).
 [PASS] Passbolt is configured to force SSL use.
 [PASS] App.fullBaseUrl is set to HTTPS.
 [PASS] Selenium API endpoints are disabled.
 [PASS] Search engine robots are told not to index content.
 [INFO] The Self Registration plugin is enabled.
 [INFO] The self registration provider is: Email domain safe list.
 [PASS] The deprecated self registration public setting was not found in /etc/passbolt/passbolt.php.
 [WARN] Host availability checking is disabled.
 [HELP] Make sure this instance is not publicly available on the internet.
 [HELP] Or set the PASSBOLT_EMAIL_VALIDATE_MX environment variable to true.
 [HELP] Or set passbolt.email.validate.mx to true in /etc/passbolt/passbolt.php.
 [PASS] Serving the compiled version of the javascript app.
 [WARN] Some email notifications are disabled by the administrator.
 [PASS] The database schema is up to date.

 Database

 [PASS] The application is able to connect to the database
 [PASS] 34 tables found.
 [PASS] Some default content is present.

 Metadata

 [PASS] The server is able to decrypt the metadata private key.
 [PASS] Active metadata key found or not required.
 [PASS] The server has access to the metadata keys or does not require access to it.
 [FAIL] The server metadata private key is not valid. Unable to validate metadata private key (id: <UUID>) cleartext data.

 [FAIL] 1 error(s) found. Hang in there!

Hello @richarson,
Did you update the fullBaseUrl after enabling E2EE metadata by any chance? I have seen similar issues some days ago and since we are also storing the domain in the encrypted JSON blob in metadata_private_keys that could explain why.

If that’s the case, don’t worry I can explain to you how to decrypt the data, update the domain and re-encrypt it to update the database.

If not, please could you share any other information that could help to identify the issues? e.g., on which version did you enable E2EE metadata, etc.

Hello @antony , thanks for the reply!

In the lab, I think it was 5.4.0 when I enabled E2EE but it could have been 5.4.1 because I accidentally left passbolt’s repo enabled and it got auto-updated.

I did modify fullBaseUrl, I’m not sure if I did it before or after enabling E2EE but I could check it’s ok if you guide me.

Hello @richarson,
In the user management interface, you should see a button that lets you “share” the missing metadata key with the affected user. Can you please do that?

This might not fix the healthCheck issue. It only ensures the missing key is shared. If you don’t see any missing-key notice, perfect. I suggest changing the domain manually to resolve the healthCheck. Please take a snapshot of the machine beforehand and, if possible, perform the change in a dedicated test environment to avoid any production risk. This is important.

To start, retrieve the server key. You can copy the contents of /etc/passbolt/gpg/serverkey_private.asc into a dedicated file (e.g., /path/to/file.gpg). Then import it with:

  • gpg --import /path/to/file.gpg

To verify the key was imported, run:

  • gpg --list-key

If the key is present, proceed to the database. Connect to the database and run:

  • SELECT data FROM metadata_private_keys WHERE id = "UUID";
    • Replace UUID with the id that is failing on your healthCheck
  • Copy the PGP message.

Disconnect from the database and create a file for this message, for example encrypted_message.gpg, and paste the content into it. Note: GPG is picky about indentation. Ensure the message starts with -----BEGIN PGP MESSAGE----- with no leading spaces.

To decrypt the message, run:
- gpg --decrypt -o decrypted_message.txt encrypted_message.gpg
Then edit the decrypted JSON blob, especially the domain field. It should contain your old domain. Replace it with your new domain and save the file.

Now encrypt the updated content with the server key:

  • gpg --output reencrypted_message.txt --encrypt --armor --recipient SERVER_KEY_EMAIL decrypted_message.txt
    • (Replace the placeholder with the email associated with the server key.)

Verify that reencrypted_message.txt contains a valid PGP message. If so, reconnect to your database and run:

  • UPDATE metadata_private_keys SET data = "NEW_PGP_MESSAGE_CONTENT" WHERE id = "UUID";
    • Again, replace the UUID with the id that is failing on your healthCheck

If everything went well, disconnect from the database and run the healthCheck again. If the error is gone, delete all the files we created. :wink: Otherwise, let us know!

4 Likes

Genius!

Thank you very much, no more healthcheck issues :+1:

3 Likes

BTW, if someone else needs to do this, I struggled to paste the new content in mysql client so I made a script to do it:

#!/bin/sh

echo 'UPDATE metadata_private_keys SET data = "-----BEGIN PGP MESSAGE-----
<REST_OF_THE_FILE>
-----END PGP MESSAGE-----" WHERE id = "<UUID>" | mysql passbolt_db

Replace “<REST_OF_THE_FILE>”, “<UUID>” and “passbolt_db” appropriately and run the script.
Possibly add authentication parameters if you don’t use a login file.

3 Likes