{"record":{"id":"2537f30bce39d451","repo":"ethereum/go-ethereum","slug":"reading-from-crypto-rand-failed","errorCode":null,"errorMessage":"reading from crypto/rand failed: ","messagePattern":"reading from crypto/rand failed: ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"accounts/keystore/passphrase.go","lineNumber":143,"sourceCode":"\t\t\t//lint:ignore ST1005 This is a message for the user\n\t\t\treturn fmt.Errorf(msg, tmpName, err)\n\t\t}\n\t}\n\treturn os.Rename(tmpName, filename)\n}\n\nfunc (ks keyStorePassphrase) JoinPath(filename string) string {\n\tif filepath.IsAbs(filename) {\n\t\treturn filename\n\t}\n\treturn filepath.Join(ks.keysDirPath, filename)\n}\n\n// EncryptDataV3 encrypts the data given as 'data' with the password 'auth'.\nfunc EncryptDataV3(data, auth []byte, scryptN, scryptP int) (CryptoJSON, error) {\n\tsalt := make([]byte, 32)\n\tif _, err := io.ReadFull(rand.Reader, salt); err != nil {\n\t\tpanic(\"reading from crypto/rand failed: \" + err.Error())\n\t}\n\tderivedKey, err := scrypt.Key(auth, salt, scryptN, scryptR, scryptP, scryptDKLen)\n\tif err != nil {\n\t\treturn CryptoJSON{}, err\n\t}\n\tencryptKey := derivedKey[:16]\n\n\tiv := make([]byte, aes.BlockSize) // 16\n\tif _, err := io.ReadFull(rand.Reader, iv); err != nil {\n\t\tpanic(\"reading from crypto/rand failed: \" + err.Error())\n\t}\n\tcipherText, err := aesCTRXOR(encryptKey, data, iv)\n\tif err != nil {\n\t\treturn CryptoJSON{}, err\n\t}\n\tmac := crypto.Keccak256(derivedKey[16:32], cipherText)\n\n\tscryptParamsJSON := make(map[string]interface{}, 5)","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/ethereum/go-ethereum/blob/6bb0588ad8e7f922e4ad5580f51265a4097af08f/accounts/keystore/passphrase.go#L125-L161","documentation":"EncryptDataV3 derives a key with scrypt and needs 32 random bytes of salt from crypto/rand before KDF. If io.ReadFull(rand.Reader, salt) fails it panics immediately with 'reading from crypto/rand failed: ' plus the cause — V3 keystore encryption cannot proceed without a fresh random salt, so the library treats a broken entropy source as fatal.","triggerScenarios":"Creating or updating a keystore account (newAccount, updateAccountPassword, ExportKey...) on a system where crypto/rand reads fail: /dev/urandom unavailable, getrandom(2) blocked by seccomp, or entropy exhaustion in a constrained VM.","commonSituations":"Minimal Docker/chroot images missing a proper /dev, restrictive sandbox profiles, very early boot on entropy-starved kernels, or exotic OSes with unimplemented getrandom.","solutions":["Provide a working OS entropy source: mount /dev/urandom correctly in the container.","On VMs add virtio-rng or install haveged.","Adjust seccomp/AppArmor policies to allow getrandom(2).","Re-run the account creation after fixing entropy; no state is corrupted because the panic happens before any file write."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func entropyCheck() error {\n\tb := make([]byte, 8)\n\tif _, err := rand.Read(b); err != nil { // crypto/rand\n\t\treturn fmt.Errorf(\"crypto/rand unusable: %w\", err)\n\t}\n\treturn nil\n}\n// call at startup before any keystore operations","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Probe crypto/rand once at service startup in sandboxed/containerized deploys.","Keep /dev/urandom available in minimal images.","Allow getrandom(2) in seccomp profiles."],"tags":["go-ethereum","keystore","entropy","encryption","panic"],"backgroundTag":null,"analyzedSha":"6bb0588ad8e7f922e4ad5580f51265a4097af08f","analyzedAt":"2026-08-15T10:06:53.996Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}