knadh/listmonk · critical

error generating Altcha HMAC key: %v

Error message

error generating Altcha HMAC key: %v

What it means

During New(), when the captcha provider is ALTCHA, a random 24-byte HMAC key is generated with crypto/rand and base64-encoded. If rand.Read fails (the OS cryptographic entropy source is unavailable), the code panics because it cannot construct a secure Altcha provider without a key.

Source

Thrown at internal/captcha/captcha.go:86

			Timeout: timeout,
			Transport: &http.Transport{
				MaxIdleConnsPerHost:   10,
				MaxConnsPerHost:       100,
				ResponseHeaderTimeout: timeout,
				IdleConnTimeout:       timeout,
			},
		},
	}

	// Determine which provider is enabled
	if o.Altcha.Enabled {
		c.provider = ProviderAltcha

		// Generate an random HMAC key for Altcha.
		b := make([]byte, 24) // 24 bytes will give 32 characters when base64 encoded
		_, err := rand.Read(b)
		if err != nil {
			panic(fmt.Sprintf("error generating Altcha HMAC key: %v", err))
		}
		hmacKey := base64.URLEncoding.EncodeToString(b)[:32]

		c.altcha = altchaOpt{
			Complexity: o.Altcha.Complexity,
			HMACKey:    hmacKey,
		}
	} else if o.HCaptcha.Enabled {
		c.provider = ProviderHCaptcha
		c.hCaptcha = hCaptchaOpt{
			Secret: o.HCaptcha.Secret,
		}
	}

	return c
}

// IsEnabled returns true if any captcha provider is enabled.

View on GitHub (pinned to 670c01717d)

Solutions

  1. Ensure the container/host exposes /dev/urandom and does not block the getrandom syscall (fix seccomp/AppArmor profile)
  2. Restart the process — crypto/rand failures are usually transient entropy exhaustion
  3. Check kernel entropy levels (cat /proc/sys/kernel/random/entropy_avail) and add a hardware RNG or haveged/jitterentropy if persistently low
  4. Remove the custom RNG redirection if crypto/rand was stubbed (e.g. in tests)
Defensive patterns

Strategy: try-catch

Validate before calling

// Health-check entropy source availability before app start
if _, err := os.Stat("/dev/urandom"); err != nil {
    panic("crypto entropy source unavailable: " + err.Error())
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        log.Fatalf("captcha init failed: %v", r) // New panics on rand failure
    }
}()
captcha, _ := captcha.New(cfg)

Prevention

When it happens

Trigger: Calling New (via initCaptcha) with ProviderAltcha configured while crypto/rand.Read returns an error — typically when the OS entropy pool is exhausted or /dev/urandom is unavailable in a restricted container.

Common situations: Highly restricted Docker/container sandboxes without proper /dev/urandom access, extremely low-entropy embedded systems or VMs at boot, or seccomp policies blocking the getrandom syscall.

Related errors


AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01). Data as JSON: /api/errors/f62c2a47ddff19d8. Report an issue: GitHub.