{"record":{"id":"a3d018f77a282a05","repo":"hyperledger/fabric","slug":"error-getting-random-bytes-a3d018","errorCode":null,"errorMessage":"error getting random bytes","messagePattern":"error getting random bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"protoutil/commonutils.go","lineNumber":287,"sourceCode":"}\n\n// EnvelopeToConfigUpdate is used to extract a ConfigUpdateEnvelope from an envelope of\n// type CONFIG_UPDATE\nfunc EnvelopeToConfigUpdate(configtx *cb.Envelope) (*cb.ConfigUpdateEnvelope, error) {\n\tconfigUpdateEnv := &cb.ConfigUpdateEnvelope{}\n\t_, err := UnmarshalEnvelopeOfType(configtx, cb.HeaderType_CONFIG_UPDATE, configUpdateEnv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn configUpdateEnv, nil\n}\n\nfunc getRandomNonce() ([]byte, error) {\n\tkey := make([]byte, 24)\n\n\t_, err := rand.Read(key)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"error getting random bytes\")\n\t}\n\treturn key, nil\n}\n\nfunc IsConfigTransaction(envelope *cb.Envelope) bool {\n\tpayload, err := UnmarshalPayload(envelope.Payload)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tif payload.Header == nil {\n\t\treturn false\n\t}\n\n\thdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn false\n\t}","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/commonutils.go#L269-L305","documentation":"getRandomNonce reads 24 cryptographically random bytes via crypto/rand; this error wraps any failure of rand.Read. It is a system-level failure (entropy source unavailable) surfaced whenever a nonce is created for a proposal or txid.","triggerScenarios":"Indirectly triggered via CreateNonce, CreateChaincodeProposalWithTransient/WithTxIDAndTransient, or CreateProposalFromCISAndTxid when crypto/rand.Read fails — e.g. entropy pool exhausted, or running in a container/sandbox where /dev/urandom is unavailable or blocked.","commonSituations":"Containers with restricted /dev/urandom access; seccomp/AppArmor profiles blocking getrandom(2); extremely low-entropy environments (rare on modern Linux); VMs without a hardware RNG early in boot.","solutions":["Ensure /dev/urandom is accessible in the container/host and not blocked by seccomp or device cgroup rules","Check kernel entropy health (dmesg for random: messages); add haveged/rngd only on legacy kernels","Retry the operation — crypto/rand failures are usually transient or environmental","If inside a custom sandbox, verify getrandom(2) syscall is permitted"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// No caller-side pre-check possible; verify entropy source availability instead:\n// In deployment: test `head -c 24 /dev/urandom > /dev/null` works in the container.\nif _, err := os.Stat(\"/dev/urandom\"); err != nil {\n\treturn fmt.Errorf(\"entropy source unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"nonce, err := protoutil.CreateNonce()\nif err != nil {\n\tif strings.Contains(err.Error(), \"random bytes\") {\n\t\t// transient/environmental: back off and retry\n\t\ttime.Sleep(backoff)\n\t\tnonce, err = protoutil.CreateNonce()\n\t}\n\tif err != nil { return fmt.Errorf(\"entropy failure, check /dev/urandom and seccomp profile: %w\", err) }\n}","preventionTips":["Ensure /dev/urandom is mounted and permitted in containers (devices cgroup, seccomp allow getrandom)","Avoid minimal runtimes that block crypto/rand syscalls","Alert on this error — it signals host-level entropy problems, not app bugs"],"tags":["fabric","crypto","entropy","nonce"],"backgroundTag":"entropy-source-unavailable","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}