labstack/echo · critical

unexpected error happened when reading from bufio.NewReader(

Error message

unexpected error happened when reading from bufio.NewReader(crypto/rand.Reader)

What it means

Panicked by randomString (util.go:93) when io.ReadFull(reader, r) fails while reading from a pooled bufio.Reader backed by crypto/rand.Reader. randomString generates request IDs (RequestID middleware), CSRF tokens (CSRF middleware), and is used in tests. A read failure from the system CSPRNG is treated as fatal because secure tokens cannot be produced.

Source

Thrown at middleware/util.go:93

	rlen := n + n/4 // perf: avoid read from rand.Reader many times
	if cap(sc.r) < rlen {
		sc.r = make([]byte, rlen)
	} else {
		sc.r = sc.r[:rlen]
	}
	b, r := sc.b, sc.r
	var i uint8 = 0

	// security note:
	// we can't just simply do b[i]=randomStringCharset[rb%len(randomStringCharset)],
	// len(len(randomStringCharset)) is 52, and rb is [0, 255], 256 = 52 * 4 + 48.
	// make the first 48 characters more possibly to be generated then others.
	// So we have to skip bytes when rb > randomStringMaxByt

	for {
		_, err := io.ReadFull(reader, r)
		if err != nil {
			panic("unexpected error happened when reading from bufio.NewReader(crypto/rand.Reader)")
		}
		for _, rb := range r {
			if rb > randomStringMaxByte {
				// Skip this number to avoid bias.
				continue
			}
			b[i] = randomStringCharset[rb%randomStringCharsetLen]
			i++
			if i == length {
				return string(b[:length])
			}
		}
	}
}

func validateOrigins(origins []string, what string) error {
	for _, o := range origins {
		if err := validateOrigin(o, what); err != nil {

View on GitHub (pinned to 05489dc173)

Solutions

  1. Ensure /dev/urandom is available and readable inside the deployment (mount it in containers).
  2. Adjust seccomp/AppArmor profiles to permit the getrandom syscall.
  3. On systems where the CSPRNG may be slow at boot, delay serving traffic until /dev/urandom is initialized.
  4. Run on a kernel version with a reliable getrandom implementation (modern Linux is fine).
Defensive patterns

Strategy: validation

Validate before calling

// Verify the system CSPRNG is readable at startup.
func checkEntropy() error {
    b := make([]byte, 16)
    _, err := io.ReadFull(rand.Reader, b)
    return err
}

if err := checkEntropy(); err != nil {
    log.Fatalf("crypto/rand unavailable: %v", err)
}

Prevention

When it happens

Trigger: The OS cryptographic random source (/dev/urandom or getrandom syscall) fails or is unavailable. This is extremely rare and usually indicates a broken or highly constrained environment: a misconfigured container with /dev/urandom unavailable, a seccomp/AppArmor profile blocking getrandom, or a depleted entropy source on older kernels.

Common situations: Containers/chroots without /dev/urandom mounted; strict seccomp filters blocking the getrandom syscall; very early boot on embedded systems before RNG initialization; sandboxed runtimes (some gVisor/WSL2 edge cases).

Related errors


AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04). Data as JSON: /data/errors/914c9eba5375720c.json. Report an issue: GitHub.