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

  1. Regenerate/verify the public key bytes and confirm they are the exact bytes the server signed the job JWT with
  2. Check the wrapped error from wavejwt.SetPublicKey to see whether it is a parse vs state problem
  3. Ensure the key is passed intact across the exec boundary (files/hex/base64, not env truncation)
  4. 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

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


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