{"id":"9125460c050782f8","repo":"gofiber/fiber","slug":"rand-read-failed-w","errorCode":null,"errorMessage":"rand.Read failed: %w","messagePattern":"rand\\.Read failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"client/hooks.go","lineNumber":53,"sourceCode":"\n\tletterBytes = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n)\n\n// unsafeRandString returns a random string of length n.\n// An error is returned if the random source fails.\nfunc unsafeRandString(n int) (string, error) {\n\tinputLength := byte(len(letterBytes))\n\n\t// Compute the largest multiple of inputLength ≤ 256 to avoid modulo bias.\n\t// Any byte ≥ max will be rejected and re‑read.\n\tmaxLength := byte(256 - (256 % int(inputLength))) //nolint:gosec // G115: integer overflow conversion int -> byte\n\n\tout := make([]byte, n)\n\tbuf := make([]byte, n)\n\n\t// Read n raw bytes in one shot\n\tif _, err := rand.Read(buf); err != nil {\n\t\treturn \"\", fmt.Errorf(\"rand.Read failed: %w\", err)\n\t}\n\n\tfor i, b := range buf {\n\t\t// Reject values ≥ maxLength\n\t\tfor b >= maxLength {\n\t\t\tif _, err := rand.Read(buf[i : i+1]); err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"rand.Read failed: %w\", err)\n\t\t\t}\n\t\t\tb = buf[i]\n\t\t}\n\t\tout[i] = letterBytes[b%inputLength]\n\t}\n\n\treturn utils.UnsafeString(out), nil\n}\n\n// parserRequestURL sets options for the hostclient and normalizes the URL.\n// It merges the baseURL with the request URI if needed and applies query and path parameters.","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/client/hooks.go#L35-L71","documentation":"Returned by unsafeRandString (client/hooks.go:53) when the initial crypto/rand.Read of n bytes fails. unsafeRandString generates random multipart-boundary strings; the first bulk read produces all n bytes at once. A failure here means the kernel could not supply cryptographic randomness, which is exceedingly rare on a healthy Linux/macOS host.","triggerScenarios":"crypto/rand.Read returns an error — typically on a system with a broken /dev/urandom, an extremely early boot before the CSPRNG is seeded, a chroot/container without /dev/urandom, or an OS-level entropy failure. Triggered during multipart file uploads when the client auto-generates a boundary.","commonSituations":"Running inside a minimal container/seccomp profile that blocks /dev/urandom reads; booting code before the kernel RNG is ready (embedded devices); a misconfigured sandbox; syscall interception (some tracing/latency tools) that breaks getrandom(2).","solutions":["Ensure /dev/urandom is available and readable inside the container/sandbox.","Loosen seccomp/AppArmor profiles to permit the getrandom syscall and /dev/urandom access.","Delay startup until the kernel CSPRNG is seeded on embedded/early-boot environments.","Handle the error from the request that triggers file uploads (it propagates up from parserRequestHeader)."],"exampleFix":"// before — upload attempted in an environment without /dev/urandom\nresp, err := client.R().SetFiles(\"./upload.txt\").Get(url)\n\n// after — guard the upload path and report the environment problem\nresp, err := client.R().SetFiles(\"./upload.txt\").Get(url)\nif err != nil && strings.Contains(err.Error(), \"rand.Read failed\") {\n    return fmt.Errorf(\"CSPRNG unavailable for boundary generation; check /dev/urandom: %w\", err)\n}","handlingStrategy":"fallback","validationCode":"// Probe the CSPRNG at startup so failures surface early.\nfunc probeCSPRNG() error {\n    b := make([]byte, 16)\n    _, err := rand.Read(b)\n    return err\n}","typeGuard":null,"tryCatchPattern":"if _, err := rand.Read(make([]byte, 16)); err != nil {\n    // CSPRNG unavailable — uploads that need a boundary will fail;\n    // fall back to a preconfigured boundary.\n    req.SetBoundary(\"FixedFallbackBoundary\")\n}","preventionTips":["Expose /dev/urandom and permit the getrandom syscall in containers/seccomp.","Probe crypto/rand at startup to fail fast in broken environments.","Set an explicit multipart boundary to bypass unsafeRandString when randomness is unavailable."],"tags":["client","crypto-rand","multipart","environment"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}