{"record":{"id":"6b7ba877b35ea50c","repo":"paragonie/random_compat","slug":"could-not-gather-sufficient-random-data-6b7ba8","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_legacy.php","lineNumber":89,"sourceCode":"                $n = ($bytes - $i) > 1073741824\n                    ? 1073741824\n                    : $bytes - $i;\n                $buf .= Sodium::randombytes_buf((int) $n);\n            }\n        } else {\n            $buf .= Sodium::randombytes_buf((int) $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":71,"sourceCodeEnd":94,"githubUrl":"https://github.com/paragonie/random_compat/blob/b5d188cc9d5e02f94d2c41da23093f1ef557c5b1/lib/random_bytes_libsodium_legacy.php#L71-L94","documentation":"Identical to error 20 but for the libsodium-legacy backend: random_bytes() has exhausted all earlier entropy sources and the final Sodium::randombytes_buf() call failed or returned false, so the library throws. random_compat intentionally fails closed when no cryptographically secure source is available.","triggerScenarios":"Calling random_bytes() on a PHP 5.x system where /dev/urandom (via mcrypt or direct read) is unavailable and the libsodium fallback also errors — reaching the throw at lib/random_bytes_libsodium_legacy.php:89.","commonSituations":"Legacy PHP 5 hosts without mcrypt or libsodium, containers without /dev/urandom, hardened systems where open_basedir blocks random device access, or broken/old libsodium builds.","solutions":["Restore a working entropy source: ensure /dev/urandom exists and is readable by the PHP process.","Install the libsodium extension (pecl install libsodium) so the fallback backend works.","Upgrade to PHP 7.0+ to use the built-in random_bytes().","Check open_basedir and disable_functions for restrictions on urandom.","Retry only after the environment is fixed; never substitute non-CSPRNG randomness."],"exampleFix":"// before\n$iv = random_bytes(16);\n// after\ntry {\n    $iv = random_bytes(16);\n} catch (Exception $e) {\n    error_log('CSPRNG unavailable on this host: ' . $e->getMessage());\n    throw $e;\n}","handlingStrategy":"try-catch","validationCode":"// Environment check at bootstrap:\n// if (!is_readable('/dev/urandom') && !function_exists('Sodium\\randombytes_buf')) {\n//     failHard('No secure RNG backend available');\n// }","typeGuard":"null","tryCatchPattern":"try {\n    $bytes = random_bytes($n);\n} catch (Exception $e) {\n    error_log('No secure RNG on legacy host: ' . $e->getMessage());\n    throw $e; // fail closed\n}","preventionTips":["Upgrade off PHP 5.x to PHP 7.0+ where possible.","Install pecl libsodium or ensure mcrypt + /dev/urandom exist on legacy hosts.","Add deployment checks that the entropy device is present and readable.","Never catch this error and fall back to non-CSPRNG randomness."],"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"}