{"record":{"id":"415b1d34ee2461ec","repo":"paragonie/random_compat","slug":"could-not-gather-sufficient-random-data-bytes-libsodium","errorCode":null,"errorMessage":"Could not gather sufficient random data","messagePattern":"Could not gather sufficient random data","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"lib/random_bytes_libsodium.php","lineNumber":87,"sourceCode":"                    ? 1073741824\n                    : $bytes - $i;\n                $buf .= \\Sodium\\randombytes_buf($n);\n            }\n        } else {\n            /** @var string|bool $buf */\n            $buf = \\Sodium\\randombytes_buf($bytes);\n        }\n\n        if (is_string($buf)) {\n            if (RandomCompat_strlen($buf) === $bytes) {\n                return $buf;\n            }\n        }\n\n        /**\n         * If we reach here, PHP has failed us.\n         */\n        throw new Exception(\n            'Could not gather sufficient random data'\n        );\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":92,"githubUrl":"https://github.com/paragonie/random_compat/blob/b5d188cc9d5e02f94d2c41da23093f1ef557c5b1/lib/random_bytes_libsodium.php#L69-L92","documentation":"This error is thrown by random_compat's libsodium-backed random_bytes() when every internal attempt to obtain random bytes fails, including the final libsodium fallback. It means the PHP environment could not provide cryptographically secure randomness through any available backend, so the library deliberately fails closed instead of returning insecure data.","triggerScenarios":"Calling random_bytes($n) on a system where PHP 7's CSPRNG is absent, /dev/urandom is unreadable, and Sodium::randombytes_buf() also fails — the function exhausts all backends and reaches the final throw in lib/random_bytes_libsodium.php:87.","commonSituations":"Running on unusual OSes without /dev/urandom, chrooted or containerized environments missing random device nodes, misconfigured open_basedir restrictions blocking /dev/urandom, or broken PHP builds lacking a working CSPRNG.","solutions":["Fix the OS-level entropy source: verify /dev/urandom exists and is readable (e.g. mount /dev properly in containers).","Upgrade to PHP 7.0+ where random_bytes() is a built-in, which bypasses this polyfill path.","Check PHP open_basedir/disable_functions settings are not blocking urandom access.","Ensure the paragonie/sodium_compat or libsodium extension is installed and functional if that backend is in play.","If the failure is transient entropy starvation, retry after the system RNG is available."],"exampleFix":"// before\n$data = random_bytes(32);\n// after\ntry {\n    $data = random_bytes(32);\n} catch (Exception $e) {\n    error_log('No CSPRNG available: ' . $e->getMessage());\n    throw $e; // do NOT fall back to insecure randomness\n}","handlingStrategy":"try-catch","validationCode":"// No caller-side check can prevent an environment-level CSPRNG failure;\n// detect it early at application bootstrap:\n// try { random_bytes(1); } catch (Exception $e) { failHard('No CSPRNG'); }","typeGuard":"null","tryCatchPattern":"try {\n    $data = random_bytes(32);\n} catch (Exception $e) {\n    // fails closed: never substitute rand()/mt_rand()\n    error_log('CSPRNG unavailable: ' . $e->getMessage());\n    throw new RuntimeException('Secure randomness unavailable', 0, $e);\n}","preventionTips":["Run on PHP 7.0+ so random_bytes() is built-in.","Verify /dev/urandom exists and is readable at deploy time in containers/chroots.","Check open_basedir and disable_functions do not block urandom access.","Add a bootstrap health check that calls random_bytes(1) and fails startup loudly if unavailable."],"tags":["php","cryptography","randomness","environment"],"backgroundTag":"unsupported-platform","analyzedSha":"b5d188cc9d5e02f94d2c41da23093f1ef557c5b1","analyzedAt":"2026-09-13T16:12:09.755Z","contentChangedAt":"2026-09-13T16:12:09.755Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}