{"record":{"id":"e2f23d1eb10a3728","repo":"passbolt/passbolt_api","slug":"cannot-generate-a-random-uuid-some-dependencies-are-missing","errorCode":null,"errorMessage":"Cannot generate a random UUID, some dependencies are missing.","messagePattern":"Cannot generate a random UUID, some dependencies are missing\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"src/Utility/UuidFactory.php","lineNumber":47,"sourceCode":"     * Needed because CakePHP Text::uuid is not cryptographically secure\n     * But also do not provide uuid5\n     *\n     * @param string|null $seed optional, used to create uuid5\n     * @return string uuid4|uuid5\n     * @throws \\Exception\n     */\n    public static function uuid(?string $seed = null): string\n    {\n        if (is_null($seed)) {\n            // Generate a version 4 (random) UUID object\n            // uses random_bytes on php7\n            // uses openssl_random_bytes on php5\n            try {\n                $uuid4 = Uuid::uuid4();\n\n                return $uuid4->toString();\n            } catch (Throwable $e) {\n                throw new Exception('Cannot generate a random UUID, some dependencies are missing.');\n            }\n        } else {\n            // Generate a version 5 (name-based and hashed with SHA1) UUID object\n            $uuid5 = Uuid::uuid5(UuidFactory::PASSBOLT_SEED, $seed);\n\n            return $uuid5->toString();\n        }\n    }\n\n    /**\n     * @param string $seed required\n     * @return string\n     */\n    public static function uuid5(string $seed): string\n    {\n        // Generate a version 5 (name-based and hashed with SHA1) UUID object\n        $uuid5 = Uuid::uuid5(UuidFactory::PASSBOLT_SEED, $seed);\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Utility/UuidFactory.php#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["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).","Upgrade PHP and the ramsey/uuid package to a version with broader random-source fallbacks (paragonie/random_compat).","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."],"exampleFix":"// before\n$id = UuidFactory::uuid(); // throws if no random source\n// after\ntry {\n    $id = UuidFactory::uuid();\n} catch (\\Exception $e) {\n    // environment lacks CSPRNG; fall back to seeded uuid5 or fix open_basedir\n    $id = UuidFactory::uuid('fallback-seed-' . microtime(true));\n}","handlingStrategy":"fallback","validationCode":"// Pre-flight: confirm a random source is usable before bulk operations\n$ok = function_exists('random_bytes') || function_exists('openssl_random_pseudo_bytes');\nif (!$ok) { throw new \\RuntimeException('PHP environment lacks a CSPRNG; UUID generation will fail.'); }","typeGuard":"function canGenerateRandomUuid(): bool {\n    try { random_bytes(16); return true; } catch (\\Throwable $e) { return false; }\n}","tryCatchPattern":"try {\n    $id = UuidFactory::uuid();\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'random UUID')) {\n        $id = UuidFactory::uuid('deterministic-seed-' . uniqid('', true)); // uuid5 fallback\n    } else { throw $e; }\n}","preventionTips":["Ensure /dev/urandom is available and not blocked by open_basedir/disable_functions in containers and chroots.","Keep PHP and ramsey/uuid up to date for robust CSPRNG fallbacks.","Add an environment health check validating random-byte generation before running migrations."],"tags":["uuid","random","environment","php"],"backgroundTag":"missing-dependency","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}