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

  1. Inspect the wrapped cause with errors.Is/As — the underlying rand.Read error names the OS-level problem (e.g. 'getrandom: function not implemented').
  2. Fix the environment: ensure /dev/urandom exists and the container runtime/seccomp profile permits getrandom(2).
  3. Upgrade the Go toolchain: modern versions fall back from getrandom to /dev/urandom instead of failing.
  4. 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.
  5. 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

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


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)