wavetermdev/waveterm · critical
failed to set public key: %w
Error message
failed to set public key: %w
What it means
SetupJobManager installs the JWT public key used to authenticate job stream requests by calling wavejwt.SetPublicKey. If that fails (e.g. the key bytes are malformed or the JWT library rejects them), this error wraps the underlying cause and aborts job manager setup.
Source
Thrown at pkg/jobmanager/jobmanager.go:60
lock sync.Mutex
attachedClient *MainServerConn
connectedStreamClient *MainServerConn
pendingStreamMeta *wshrpc.StreamMeta
}
func SetupJobManager(clientId string, jobId string, publicKeyBytes []byte, jobAuthToken string, readyFile *os.File) error {
if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
return fmt.Errorf("job manager only supported on unix systems, not %s", runtime.GOOS)
}
WshCmdJobManager.ClientId = clientId
WshCmdJobManager.JobId = jobId
WshCmdJobManager.JwtPublicKey = publicKeyBytes
WshCmdJobManager.JobAuthToken = jobAuthToken
WshCmdJobManager.StreamManager = MakeStreamManager()
WshCmdJobManager.InputQueue = utilds.MakeQuickReorderQueue[wshrpc.CommandJobInputData](JobInputQueueSize, JobInputQueueTimeout)
err := wavejwt.SetPublicKey(publicKeyBytes)
if err != nil {
return fmt.Errorf("failed to set public key: %w", err)
}
err = MakeJobDomainSocket(clientId, jobId)
if err != nil {
return err
}
go func() {
defer func() {
panichandler.PanicHandler("JobManager:processInputQueue", recover())
}()
WshCmdJobManager.processInputQueue()
}()
fmt.Fprintf(readyFile, JobManagerStartLabel+"\n")
readyFile.Close()
err = daemonize(clientId, jobId)
if err != nil {View on GitHub (pinned to a4447c1563)
Solutions
- Regenerate/verify the public key bytes and confirm they are the exact bytes the server signed the job JWT with
- Check the wrapped error from wavejwt.SetPublicKey to see whether it is a parse vs state problem
- Ensure the key is passed intact across the exec boundary (files/hex/base64, not env truncation)
- Confirm client and server are the same Wave version so key formats match
Example fix
// before
pub, _ := os.ReadFile(keyPath)
SetupJobManager(cid, jid, pub, token, rf) // possibly empty/partial
// after
pub, err := os.ReadFile(keyPath)
if err != nil || len(pub) == 0 {
return fmt.Errorf("missing or empty public key file %s", keyPath)
}
SetupJobManager(cid, jid, pub, token, rf) Defensive patterns
Strategy: validation
Validate before calling
if len(publicKeyBytes) == 0 {
return fmt.Errorf("public key is empty")
}
if _, err := wavejwt.ParsePublicKey(publicKeyBytes); err != nil {
return fmt.Errorf("malformed public key: %w", err)
} Try / catch
if err := jobmanager.SetupJobManager(cid, jid, pub, tok, rf); err != nil {
if strings.Contains(err.Error(), "failed to set public key") {
// regenerate key material / re-fetch from server, then retry setup once
return
}
return err
} Prevention
- Pass key bytes verbatim (base64/hex) across process boundaries, not raw env strings
- Keep client and server on matching versions so key formats agree
- Validate key parseability before daemon launch
- Log key length (not contents) on failure for diagnosis
When it happens
Trigger: publicKeyBytes are empty, truncated, or not a valid PEM/ed25519 public key; key generated by a mismatched algorithm or corrupted in transit; SetPublicKey called twice with incompatible state.
Common situations: Auth token/public key serialized incorrectly between the main server and the job manager daemon process; an upgraded key format (algorithm change) not matching what wavejwt expects; a copied key file missing its last bytes.
Related errors
- error setting jwt public key: %v
- error making jwt token: %w
- error making jwt token: %w
- error decoding jwt public key: %w
- error setting jwt public key: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/e76572a40d4489bf.
Report an issue: GitHub.