{"record":{"id":"0cd27af722ea450b","repo":"hashicorp/nomad","slug":"could-not-read-from-random-source-v","errorCode":null,"errorMessage":"could not read from random source: %v","messagePattern":"could not read from random source: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"helper/crypto/crypto.go","lineNumber":21,"sourceCode":"\npackage crypto\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t// note: this is aliased so that it's more noticeable if someone\n\t// accidentally swaps it out for math/rand via running goimports\n\tcryptorand \"crypto/rand\"\n)\n\n// Bytes gets a slice of cryptographically random bytes of the given length and\n// enforces that we check for short reads to avoid entropy exhaustion.\nfunc Bytes(length int) ([]byte, error) {\n\tkey := make([]byte, length)\n\tn, err := cryptorand.Read(key)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not read from random source: %v\", err)\n\t}\n\tif n < length {\n\t\treturn nil, errors.New(\"entropy exhausted\")\n\t}\n\treturn key, nil\n}\n","sourceCodeStart":3,"sourceCodeEnd":28,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/crypto/crypto.go#L3-L28","documentation":"Bytes() in helper/crypto reads length bytes from crypto/rand and wraps any read failure with 'could not read from random source: %v'. The library throws it because a failing random source makes generating cryptographic keys unsafe; it refuses to return weak or partial key material. The companion 'entropy exhausted' error covers short reads.","triggerScenarios":"Calling Bytes(n) (directly or via Generate, encryptDEK, or NewUnwrappedRootKey) when the underlying crypto/rand read returns an error — e.g. getrandom(2)/getentropy syscall failure, or /dev/urandom inaccessible on old platforms.","commonSituations":"Container sandboxes or seccomp profiles blocking getrandom; extremely old kernels lacking getrandom with /dev/urandom misconfigured; fd exhaustion preventing the random-source file from being opened; VMs under heavy entropy pressure on legacy hosts.","solutions":["Check the wrapped %v cause to identify the syscall-level failure (errno) and fix that (e.g. allow getrandom in seccomp/AppArmor profile).","Verify /dev/urandom exists and is readable in the container/host if on a legacy kernel path.","Fix file-descriptor exhaustion (raise ulimit -n, close leaked fds) if the cause is EMFILE/ENFILE.","Retry the operation once the OS-level entropy source is healthy; crypto/rand self-heals once the underlying syscall succeeds."],"exampleFix":"// before\nkey, err := crypto.Bytes(32)\n// treat as retryable fatal log\nclog.Error(err)\n// after\nkey, err := crypto.Bytes(32)\nif err != nil {\n\t// inspect cause: strings.Contains(err.Error(), \"getrandom\") etc.\n\treturn fmt.Errorf(\"key generation unavailable, check entropy source: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// No pre-call check is reliable for OS entropy; optionally preflight the source on legacy systems:\nif _, err := os.Stat(\"/dev/urandom\"); err != nil {\n\treturn fmt.Errorf(\"random source unavailable: %w\", err)\n}","typeGuard":"func isRandomSourceError(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"could not read from random source\")\n}","tryCatchPattern":"key, err := crypto.Bytes(32)\nif err != nil {\n\tif isRandomSourceError(err) {\n\t\t// inspect wrapped cause, fix entropy/syscall config, then retry once\n\t}\n\treturn err\n}","preventionTips":["Allow the getrandom/getentropy syscalls in container seccomp and LSM profiles","Keep kernels reasonably modern so getrandom(2) is available","Monitor fd usage; avoid EMFILE on the random source","Treat crypto/rand failures as fatal — never fall back to math/rand for key material"],"tags":["crypto","entropy","random-source","filesystem"],"backgroundTag":"entropy-source-unavailable","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}