MHSanaei/3x-ui · error

failed to generate UUID: %w

Error message

failed to generate UUID: %w

What it means

Returned by ServerService.GetNewUUID when google/uuid's NewRandom() fails. NewRandom reads 16 bytes from crypto/rand, so this error almost always means the OS random source could not be read (EAGAIN on getrandom(2), a blocked entropy pool on early-boot kernels, or a fd/ulimit exhaustion in constrained containers). It is not related to UUID formatting or duplication.

Source

Thrown at internal/web/service/server.go:2380

	return auths
}

func vlessEncAuthID(label string) string {
	normalized := strings.NewReplacer("-", "", "_", "", " ", "").Replace(strings.ToLower(label))
	switch {
	case strings.Contains(normalized, "mlkem768"):
		return "mlkem768"
	case strings.Contains(normalized, "x25519"):
		return "x25519"
	default:
		return normalized
	}
}

func (s *ServerService) GetNewUUID() (map[string]string, error) {
	newUUID, err := uuid.NewRandom()
	if err != nil {
		return nil, fmt.Errorf("failed to generate UUID: %w", err)
	}

	return map[string]string{
		"uuid": newUUID.String(),
	}, nil
}

func (s *ServerService) GetNewmlkem768() (any, error) {
	// Run the command
	cmd := exec.CommandContext(context.Background(), xray.GetBinaryPath(), "mlkem768")
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		return nil, err
	}

	seed, client, err := parseXrayKeyPairOutput(out.String())

View on GitHub (pinned to ad32144c42)

Solutions

  1. Check host entropy/CRNG state: cat /proc/sys/kernel/random/entropy_info or dmesg for 'crng init done'; if not initialized, wait or add a hardware RNG (haveged is a last resort).
  2. Inspect the panel logs for the wrapped error text — the %w chain names the syscall reason (e.g. 'resource temporarily unavailable' = fd/pressure, 'operation not permitted' = seccomp).
  3. If running in a restricted container, allow getrandom(2) in the seccomp profile or raise the fd limit (ulimit -n) and restart the panel.
  4. Retry the request once; transient EAGAIN on getrandom is self-healing.

Example fix

// before
newUUID, err := uuid.NewRandom()
if err != nil {
    return nil, fmt.Errorf("failed to generate UUID: %w", err)
}

// after (caller side, e.g. controller): keep the guard, surface a retryable hint
newUUID, err := uuid.NewRandom()
if err != nil {
    return nil, fmt.Errorf("failed to generate UUID (host random source unavailable, check crng/fd limits): %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

// In Go: capture and surface the wrapped syscall cause; retry once only for EAGAIN-style transients
newUUID, err := uuid.NewRandom()
if err != nil {
    if errors.Is(err, syscall.EAGAIN) {
        time.Sleep(50 * time.Millisecond)
        newUUID, err = uuid.NewRandom()
    }
    if err != nil {
        return fmt.Errorf("uuid generation failed (host random source issue): %w", err)
    }
}

Prevention

When it happens

Trigger: Any call to the panel endpoint that generates a new client UUID (e.g. the 'new UUID' button in the client editor) on a host where crypto/rand.Read returns an error: early-boot VM before the CRNG is seeded, a seccomp/container profile blocking getrandom, or process fd exhaustion.

Common situations: Small embedded/VM images booted straight into the panel, hardened container runtimes, or hosts under fd pressure. On modern kernels (5.6+) getrandom never blocks after seeding, so this is rare; older kernels can block at boot.

Related errors


AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15). Data as JSON: /api/errors/4b7c4146ed2919bc. Report an issue: GitHub.