OpenNHP/opennhp · error
failed to generate UUID v4
Error message
failed to generate UUID v4: %w
What it means
GenerateUUIDv4 wraps any failure from github.com/google/uuid's uuid.NewRandom() with the message 'failed to generate UUID v4: %w'. NewRandom reads cryptographic randomness (crypto/rand); if the OS entropy source is unavailable the call fails and this error is returned instead of a UUID string. It preserves the underlying cause via %w for errors.Is/As inspection.
Solutions
- Inspect the wrapped cause with errors.Is/As — the underlying rand.Read error names the OS-level problem (e.g. 'getrandom: function not implemented').
- Fix the environment: ensure /dev/urandom exists and the container runtime/seccomp profile permits getrandom(2).
- Upgrade the Go toolchain: modern versions fall back from getrandom to /dev/urandom instead of failing.
- If failures are persistent in a sandbox, generate UUIDs via uuid.New() (V4 with the same entropy) only after verifying crypto/rand works, or run the process with a less restrictive profile.
- Retry the call once on transient entropy errors before failing the registration/policy operation.
Example fix
// before
u, err := uuid.NewRandom()
if err != nil {
return "", fmt.Errorf("failed to generate UUID v4: %w", err)
}
// after
u, err := uuid.NewRandom()
if err != nil {
if errors.Is(err, rand.ErrUnsupported) {
// entropy unavailable: surface a targeted, actionable message
return "", fmt.Errorf("failed to generate UUID v4: system entropy source unavailable: %w", err)
}
return "", fmt.Errorf("failed to generate UUID v4: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Best-effort pre-check that the entropy source is usable before generating UUIDs
if f, err := os.Open("/dev/urandom"); err != nil {
return fmt.Errorf("entropy source unavailable: %w", err)
} else {
f.Close()
} Try / catch
id, err := nhputils.GenerateUUIDv4()
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) {
// entropy source problem: fall back or abort with clear context
}
return fmt.Errorf("cannot create request id: %w", err)
} Prevention
- Run in environments where /dev/urandom is present and getrandom(2) is permitted by seccomp/AppArmor.
- Check errors.Is(err, rand.ErrUnsupported) to distinguish missing entropy support from other failures.
- Retry once on transient entropy errors before failing registration/policy creation.
- Keep the Go toolchain current — newer versions handle getrandom fallbacks more robustly.
When it happens
Trigger: Calling GenerateUUIDv4 (directly or via registerTAService, NewSmartPolicy, or TestGenerateUUIDv4) when the kernel CSPRNG cannot serve random bytes — e.g. uuid.NewRandom returns a rand.Read error.
Common situations: Running on restricted/hardened containers or VMs with a broken or missing /dev/urandom; seccomp/AppArmor profiles blocking getrandom(2); extremely early boot environments before entropy initialization; exotic platforms where crypto/rand is stubbed.
Understand the failure class
Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.
Related errors
- failed to generate UUID:
- invalid input key
- error generating spoId
- fail to generate session id
- missing remote peer public key
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/43ec64c461c4289b.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/utils/uuid.go:49
// RandNumber returns a random 4-digit number (1000-10999) for non-security purposes.
//
//nolint:gosec // G404: math/rand is acceptable for non-security random numbers
func RandNumber() int {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
randomNumber := rng.Intn(10000)
if randomNumber < 1000 {
randomNumber += 1000
}
return randomNumber
}
// GenerateUUIDv4 creates a random UUID (version 4)
func GenerateUUIDv4() (string, error) {
u, err := uuid.NewRandom()
if err != nil {
return "", fmt.Errorf("failed to generate UUID v4: %w", err)
}
return u.String(), nil
}
View on GitHub (pinned to 6e04ca5ff0)