wavetermdev/waveterm · error

error setting jwt public key: %w

Error message

error setting jwt public key: %w

What it means

InitMainServer installs the public key via wavejwt.SetPublicKey. This error means the decoded bytes were rejected as an ed25519 public key (wrong size/format), preventing JWT verification from being configured and aborting startup.

Source

Thrown at pkg/wcore/wcore.go:214

		}
	}

	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)
	if err != nil {
		return fmt.Errorf("error decoding jwt public key: %w", err)
	}

	err = wavejwt.SetPrivateKey(privateKeyBytes)
	if err != nil {
		return fmt.Errorf("error setting jwt private key: %w", err)
	}
	err = wavejwt.SetPublicKey(publicKeyBytes)
	if err != nil {
		return fmt.Errorf("error setting jwt public key: %w", err)
	}

	pubKeyDer, err := x509.MarshalPKIXPublicKey(ed25519.PublicKey(publicKeyBytes))
	if err != nil {
		log.Printf("warning: could not marshal public key for logging: %v", err)
	} else {
		pubKeyPem := pem.EncodeToMemory(&pem.Block{
			Type:  "PUBLIC KEY",
			Bytes: pubKeyDer,
		})
		log.Printf("JWT Public Key:\n%s", string(pubKeyPem))
	}

	return nil
}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Clear both Jwt keys so a fresh pair is generated on next start
  2. Verify the decoded public key is exactly 32 bytes; if it is 64 bytes the fields are swapped — exchange them
  3. Regenerate with wavejwt.GenerateKeyPair and store each key StdEncoding-base64 encoded
  4. Cross-check the wrapped error's expected-size message against your data

Example fix

// diagnose
b, _ := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey)
// len(b) == 64 -> fields swapped
mainServer.JwtPublicKey, mainServer.JwtPrivateKey = mainServer.JwtPrivateKey, mainServer.JwtPublicKey // then clear & regenerate if still failing
Defensive patterns

Strategy: validation

Validate before calling

b, err := base64.StdEncoding.DecodeString(mainServer.JwtPublicKey)
if err != nil || len(b) != ed25519.PublicKeySize {
    mainServer.JwtPublicKey = "" // force regeneration
}

Type guard

func isEd25519PublicKey(b []byte) bool { return len(b) == ed25519.PublicKeySize }

Try / catch

if err := wcore.InitMainServer(); err != nil {
    if strings.Contains(err.Error(), "setting jwt public key") {
        regenerateJwtKeys()
        return wcore.InitMainServer()
    }
    panic(err)
}

Prevention

When it happens

Trigger: wavejwt.SetPublicKey(publicKeyBytes) returns an error because publicKeyBytes is not ed25519.PublicKeySize (32) bytes — a private key stored in the public-key field, truncation, or wrong-algorithm bytes.

Common situations: Swapped key fields in the DB; hand-pasted keys of the wrong type; partial DB corruption; migration from another key format.

Related errors


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