wavetermdev/waveterm · error

error generating jwt keypair: %w

Error message

error generating jwt keypair: %w

What it means

InitMainServer generates a new ed25519 key pair via wavejwt.GenerateKeyPair when the MainServer singleton has no stored JWT keys. If key generation fails, this error wraps the cause and aborts startup. Key generation on a modern host essentially never fails except under extreme resource exhaustion.

Source

Thrown at pkg/wcore/wcore.go:185

	mainServer, err := wstore.DBGetSingleton[*waveobj.MainServer](ctx)
	if err == wstore.ErrNotFound {
		mainServer = &waveobj.MainServer{
			OID: uuid.NewString(),
		}
		err = wstore.DBInsert(ctx, mainServer)
		if err != nil {
			return fmt.Errorf("error inserting mainserver: %w", err)
		}
	} else if err != nil {
		return fmt.Errorf("error getting mainserver: %w", err)
	}

	needsUpdate := false
	if mainServer.JwtPrivateKey == "" || mainServer.JwtPublicKey == "" {
		keyPair, err := wavejwt.GenerateKeyPair()
		if err != nil {
			return fmt.Errorf("error generating jwt keypair: %w", err)
		}
		mainServer.JwtPrivateKey = base64.StdEncoding.EncodeToString(keyPair.PrivateKey)
		mainServer.JwtPublicKey = base64.StdEncoding.EncodeToString(keyPair.PublicKey)
		needsUpdate = true
	}

	if needsUpdate {
		err = wstore.DBUpdate(ctx, mainServer)
		if err != nil {
			return fmt.Errorf("error updating mainserver: %w", err)
		}
	}

	privateKeyBytes, err := base64.StdEncoding.DecodeString(mainServer.JwtPrivateKey)
	if err != nil {
		return fmt.Errorf("error decoding jwt private key: %w", err)
	}
	publicKeyBytes, err := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Check the wrapped cause in logs; if it is a crypto/rand failure, verify /dev/urandom is accessible inside the container/sandbox
  2. Restart the process — key generation is transient and typically succeeds on retry
  3. Confirm Go runtime and OS are supported; update to a current Go/app version
  4. Check system memory and resource limits (ulimit, cgroup limits)
Defensive patterns

Strategy: retry

Validate before calling

// ensure entropy source is available (Linux)
if _, err := os.Stat("/dev/urandom"); err != nil {
    log.Fatal("crypto entropy source unavailable")
}

Try / catch

err := wcore.InitMainServer()
for i := 0; err != nil && i < 3; i++ {
    time.Sleep(time.Duration(i+1) * 200 * time.Millisecond)
    err = wcore.InitMainServer()
}
if err != nil { log.Fatalf("init: %v", err) }

Prevention

When it happens

Trigger: First run (or after keys were cleared) where MainServer.JwtPrivateKey or JwtPublicKey is empty and crypto/rand's ed25519.GenerateKey returns an error — e.g. the OS entropy source (/dev/urandom) is unavailable or the process is severely resource-starved.

Common situations: Running in a hardened/sandboxed container with restricted access to the kernel RNG; extreme memory pressure; exotic platforms with broken crypto/rand.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/a6a64dfc5c88ca9c. Report an issue: GitHub.