passbolt/passbolt_api · error · Exception

Can not upgrade. Please upgrade to the latest 1.x version…

Error message

Can not upgrade. Please upgrade to the latest 1.x version first and retry. See https://help.passbolt.com/hosting/update.

What it means

Thrown by Gnupg::setDecryptKeyFromFingerprint when gnupg_adddecryptkey() fails for a key that should already exist in the keyring, identified by fingerprint. Same failure family as setDecryptKey but without an import step: the key must already be present and usable with the given passphrase. The gnupg exception message is appended.

Solutions

  1. Run `gpg --list-keys --fingerprint` in the GNUPGHOME used by the app to confirm the key exists.
  2. Verify the passphrase is correct for that specific key.
  3. Re-import the private key (importKeyIntoKeyring / setDecryptKey) then retry.
  4. Confirm the configured fingerprint matches the current server key (no stale value).
  5. Check GNUPGHOME env var and directory ownership of the web server user.

Example fix

// before
$gpg->setDecryptKeyFromFingerprint($staleFingerprint, $pass);
// after
$fingerprint = $gpg->importKeyIntoKeyring($armoredPrivateKey);
$gpg->setDecryptKeyFromFingerprint($fingerprint, $correctPass);
Defensive patterns

Strategy: validation

Validate before calling

$keys = shell_exec('GNUPGHOME=' . $home . ' gpg --list-keys --with-colons ' . escapeshellarg($fingerprint));
if ($keys === null || trim($keys) === '') {
    throw new InvalidArgumentException('Fingerprint not present in keyring: ' . $fingerprint);
}

Type guard

function isFingerprint(string $f): bool {
    return (bool) preg_match('/^[0-9A-F]{40}$/i', str_replace(' ', '', $f));
}

Try / catch

try {
    $gpg->setDecryptKeyFromFingerprint($fp, $pass);
} catch (\Cake\Core\Exception\Exception $e) {
    $this->log('adddecryptkey failed for ' . $fp . ': ' . $e->getMessage());
    throw new ServerKeyConfigurationException(previous: $e);
}

Prevention

When it happens

Trigger: Calling setDecryptKeyFromFingerprint($fingerprint, $passphrase) where the fingerprint is not in the keyring, the passphrase mismatches, or the key has no secret part usable for decryption.

Common situations: Fingerprint typo/case mismatch against keyring contents; key removed from GNUPGHOME (e.g. recreated container); stale fingerprint in config after key regeneration; wrong passphrase.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/a25a69dc3bdec7bf. Report an issue: GitHub.

Appendix: source

Thrown at config/Migrations/20170830064410_V162InitialMigration.php:59

        foreach ($tables as $table) {
            $exists = $this->hasTable($table);
            if ($exists) {
                $tableCount++;
            }
        }
        // If this is an upgrade from v1
        if ($tableCount > 0 && $tableCount < sizeof($tables)) {
            throw new Exception('Can not upgrade. Some tables are missing.');
        }

        // If this is an upgrade from v1
        if ($tableCount > 0) {
            // Check the latest 1.x migration is done
            $latestMigrationName = 'Migration_1_6_1';
            $schemaMigrationResult = $this->query("SELECT * FROM schema_migrations WHERE class='$latestMigrationName'");
            $schemaMigrationRows = $schemaMigrationResult->fetchAll();
            if (!count($schemaMigrationRows)) {
                throw new Exception('Can not upgrade. Please upgrade to the latest 1.x version first and retry. See https://help.passbolt.com/hosting/update.');
            }
        }

        // Reset the collation just in case
        if ($this->getAdapter()->getAdapterType() !== "pgsql") {
            $this->execute('ALTER DATABASE `' . $databaseName . '` COLLATE utf8mb4_unicode_ci');
       }


        // If this is an upgrade from v1
        if ($tableCount > 0) {
            // Alter collation
            foreach ($tables as $table) {
                $this->execute('ALTER TABLE ' . $table . ' COLLATE utf8mb4_unicode_ci');
            }

            return;
        }

View on GitHub (pinned to 31c1bbc10f)