passbolt/passbolt_api · error · SubscriptionRecordNotFoundException
Subscription key could not be found.
Error message
Subscription key could not be found.
What it means
SubscriptionsTable::getOrFail() throws SubscriptionRecordNotFoundException ('Subscription key could not be found.') when the subscriptions table contains no row at all — find()->firstOrFail() finds nothing and the catch converts any failure into this domain exception. It signals that no subscription key has ever been installed on this instance.
Solutions
- Install a subscription key: POST /subscription with the base64 key as an admin, or use the passbolt CLI subscription command.
- Check the table is not empty: `SELECT * FROM subscriptions;` — if empty, add a valid key.
- If a key was recently deleted, re-import it from the passbolt account portal.
Example fix
// before: reading subscription on a fresh install fails
$subscription = $this->Subscriptions->getOrFail();
// after: guard for absence first
try {
$subscription = $this->Subscriptions->getOrFail();
} catch (SubscriptionRecordNotFoundException $e) {
// no key installed yet — prompt admin to import one
} Defensive patterns
Strategy: try-catch
Validate before calling
$exists = $this->Subscriptions->find()->count() > 0;
if (!$exists) { /* no key installed — handle setup flow */ } Try / catch
try {
$subscription = $this->Subscriptions->getOrFail();
} catch (SubscriptionRecordNotFoundException $e) {
// no subscription key installed — show onboarding / import UI
} Prevention
- Import the subscription key as part of deployment runbooks
- Check subscription presence in install/upgrade health checks
- Restore the subscriptions row when restoring DB backups
When it happens
Trigger: Calling getOrFail() (or higher-level reads like the subscription status endpoint) on a fresh passbolt install where no subscription key was imported yet, or after the subscription row was deleted (e.g. via SubscriptionKeyDeleteService).
Common situations: Fresh EE deployment where the admin hasn't posted the subscription key yet; subscription deleted via DELETE /subscription; database restored without the subscriptions row; running license checks during setup before key entry.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- The subscription key format is not valid.
- " " is not a valid search filter.
- " " is not a valid search filter. It is not a UTF8 string.
- " " is not a valid search filter. It should be between 1…
- " " is not a valid user filter.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/22f025aa31de3931.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Subscription/src/Model/Table/SubscriptionsTable.php:137
*/
public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options): void
{
$data['property'] = $this->getProperty();
$data['property_id'] = $this->getPropertyId();
$data['value'] = trim($data['value'] ?? '');
$data['value'] = trim($data['value'], '\'"');
}
/**
* @return \Cake\Datasource\EntityInterface|array
* @throws \Passbolt\Subscription\Error\Exception\Subscriptions\SubscriptionRecordNotFoundException
*/
public function getOrFail(): EntityInterface|array
{
try {
return $this->find()->firstOrFail();
} catch (Exception $e) {
throw new SubscriptionRecordNotFoundException();
}
}
/**
* @inheritDoc
*/
public function exists($conditions = []): bool
{
return parent::exists($conditions);
}
/**
* @param string $asciiKey Subscription key string.
* @param \App\Utility\UserAccessControl $uac Reporting who is acting.
* @return string the key as original string
*/
public function create(string $asciiKey, UserAccessControl $uac): string
{View on GitHub (pinned to 31c1bbc10f)