passbolt/passbolt_api · critical · Exception

Cannot generate a random UUID, some dependencies are…

Error message

Cannot generate a random UUID, some dependencies are missing.

What it means

UuidFactory::uuid() generates UUIDs with the ramsey/uuid library. In random mode (no seed) it calls Uuid::uuid4(); if that throws (e.g. missing os-random source or openssl random functions unavailable), the catch block rethrows a generic Exception saying random UUID dependencies are missing.

Solutions

  1. Fix the PHP environment so a CSPRNG is available: ensure /dev/urandom is accessible and openssl/random functions are not disabled (check open_basedir, disable_functions).
  2. Upgrade PHP and the ramsey/uuid package to a version with broader random-source fallbacks (paragonie/random_compat).
  3. If determinism is acceptable for the use case, call UuidFactory::uuid($seed) with a seed to use the uuid5 (SHA1 name-based) path instead of uuid4.

Example fix

// before
$id = UuidFactory::uuid(); // throws if no random source
// after
try {
    $id = UuidFactory::uuid();
} catch (\Exception $e) {
    // environment lacks CSPRNG; fall back to seeded uuid5 or fix open_basedir
    $id = UuidFactory::uuid('fallback-seed-' . microtime(true));
}
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-flight: confirm a random source is usable before bulk operations
$ok = function_exists('random_bytes') || function_exists('openssl_random_pseudo_bytes');
if (!$ok) { throw new \RuntimeException('PHP environment lacks a CSPRNG; UUID generation will fail.'); }

Type guard

function canGenerateRandomUuid(): bool {
    try { random_bytes(16); return true; } catch (\Throwable $e) { return false; }
}

Try / catch

try {
    $id = UuidFactory::uuid();
} catch (\Exception $e) {
    if (str_contains($e->getMessage(), 'random UUID')) {
        $id = UuidFactory::uuid('deterministic-seed-' . uniqid('', true)); // uuid5 fallback
    } else { throw $e; }
}

Prevention

When it happens

Trigger: Calling UuidFactory::uuid() with no seed when the underlying random source fails — Uuid::uuid4() throwing because neither /dev/urandom (open_basedir/disable_functions restrictions) nor openssl_random_pseudo_bytes is usable in the PHP environment.

Common situations: Hardened/chrooted or containerized PHP where /dev/urandom is inaccessible; disable_functions or open_basedir blocking random sources; very old PHP builds without a suitable CSPRNG; migrations/CLI commands running in a stripped environment (callers include migration up/change methods).

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/Utility/UuidFactory.php:47

     * Needed because CakePHP Text::uuid is not cryptographically secure
     * But also do not provide uuid5
     *
     * @param string|null $seed optional, used to create uuid5
     * @return string uuid4|uuid5
     * @throws \Exception
     */
    public static function uuid(?string $seed = null): string
    {
        if (is_null($seed)) {
            // Generate a version 4 (random) UUID object
            // uses random_bytes on php7
            // uses openssl_random_bytes on php5
            try {
                $uuid4 = Uuid::uuid4();

                return $uuid4->toString();
            } catch (Throwable $e) {
                throw new Exception('Cannot generate a random UUID, some dependencies are missing.');
            }
        } else {
            // Generate a version 5 (name-based and hashed with SHA1) UUID object
            $uuid5 = Uuid::uuid5(UuidFactory::PASSBOLT_SEED, $seed);

            return $uuid5->toString();
        }
    }

    /**
     * @param string $seed required
     * @return string
     */
    public static function uuid5(string $seed): string
    {
        // Generate a version 5 (name-based and hashed with SHA1) UUID object
        $uuid5 = Uuid::uuid5(UuidFactory::PASSBOLT_SEED, $seed);

View on GitHub (pinned to 31c1bbc10f)