{"record":{"id":"77c9d9fb596f0f3d","repo":"nats-io/nats-server","slug":"not-enough-seed-bytes-read-d-d","errorCode":null,"errorMessage":"not enough seed bytes read (%d != %d","messagePattern":"not enough seed bytes read \\((.+?) != (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/filestore.go","lineNumber":916,"sourceCode":"\trb, err := fs.prf([]byte(context))\n\tif err != nil {\n\t\treturn nil, nil, nil, nil, err\n\t}\n\n\tsc := fs.fcfg.Cipher\n\n\tkek, err := genEncryptionKey(sc, rb)\n\tif err != nil {\n\t\treturn nil, nil, nil, nil, err\n\t}\n\t// Generate random asset encryption key seed.\n\n\tconst seedSize = 32\n\tseed = make([]byte, seedSize)\n\tif n, err := rand.Read(seed); err != nil {\n\t\treturn nil, nil, nil, nil, err\n\t} else if n != seedSize {\n\t\treturn nil, nil, nil, nil, fmt.Errorf(\"not enough seed bytes read (%d != %d\", n, seedSize)\n\t}\n\n\taek, err = genEncryptionKey(sc, seed)\n\tif err != nil {\n\t\treturn nil, nil, nil, nil, err\n\t}\n\n\t// Generate our nonce. Use same buffer to hold encrypted seed.\n\tnonce := make([]byte, kek.NonceSize(), kek.NonceSize()+len(seed)+kek.Overhead())\n\tif n, err := rand.Read(nonce); err != nil {\n\t\treturn nil, nil, nil, nil, err\n\t} else if n != len(nonce) {\n\t\treturn nil, nil, nil, nil, fmt.Errorf(\"not enough nonce bytes read (%d != %d)\", n, len(nonce))\n\t}\n\n\tbek, err = genBlockEncryptionKey(sc, seed[:], nonce)\n\tif err != nil {\n\t\treturn nil, nil, nil, nil, err","sourceCodeStart":898,"sourceCodeEnd":934,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/filestore.go#L898-L934","documentation":"This error is thrown when crypto/rand.Read fills the 32-byte seed buffer with fewer bytes than requested while generating the encryption keys for a file store stream. In Go, crypto/rand.Read is documented to always succeed or return an error, so a short read signals a broken/failed entropy source. The store treats it as unrecoverable and aborts key generation.","triggerScenarios":"Calling stream/filestore setup (e.g. creating an encrypted file store via AddStream with a crypto-principalled account) when the OS entropy source fails mid-Read, returning n < 32 without an error.","commonSituations":"Container/kernel environments with exhausted or blocked getrandom(2), unusual sandboxed VMs, or custom rand.Source replacement hacks on Linux hosts with depleted entropy.","solutions":["Check host entropy health (e.g. /proc/sys/kernel/random/entropy_avail, getrandom availability) and fix the OS/environment issue","Retry the operation once entropy is available; crypto/rand short reads are almost always transient environment faults","Upgrade Go/runtime and OS kernel so crypto/rand.Read behavior matches modern guarantees","Remove any wrappers or LD_PRELOAD interposers that interfere with system randomness"],"exampleFix":"// before\nif n, err := rand.Read(seed); err != nil {\n    return nil, err\n} else if n != seedSize {\n    return nil, fmt.Errorf(\"not enough seed bytes read (%d != %d\", n, seedSize)\n}\n// after\n// fix the environment first; no code change fixes a failing entropy source.\n// At minimum, close the missing paren when logging:\nreturn nil, fmt.Errorf(\"not enough seed bytes read (%d != %d)\", n, seedSize)","handlingStrategy":"validation","validationCode":"if n, err := crypto_rand.Read(seed); err != nil || n != len(seed) {\n    return fmt.Errorf(\"entropy source unhealthy: read %d/%d bytes (err=%v)\", n, len(seed), err)\n}","typeGuard":null,"tryCatchPattern":"// Go: check both error and short read\nn, err := rand.Read(seed)\nif err != nil {\n    return fmt.Errorf(\"rand.Read failed: %w\", err)\n}\nif n != len(seed) {\n    return fmt.Errorf(\"short entropy read: %d != %d\", n, len(seed))\n}","preventionTips":["Monitor host entropy health (getrandom availability, entropy_avail)","Keep kernels and Go runtime up to date","Avoid sandboxes/seccomp profiles that block system randomness syscalls","Alert on any crypto/rand error in server logs"],"tags":["crypto","entropy","filestore"],"backgroundTag":"entropy-short-read","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}