wavetermdev/waveterm · error

error extracting socket name from JWT: %v

Error message

error extracting socket name from JWT: %v

What it means

serverRunRouterDomainSocket extracts the upstream socket name embedded in the JWT token using wshutil.ExtractUnverifiedSocketName (unverified, client-side). This error is wrapped when the token is missing, malformed, or lacks the socket-name claim. It indicates the JWT passed to `wsh connserver` is not a valid connection token produced by the Wave server.

Source

Thrown at cmd/wsh/cmd/wshcmd-connserver.go:294

	// run the sysinfo loop
	go func() {
		defer func() {
			panichandler.PanicHandler("serverRunRouter:RunSysInfoLoop", recover())
		}()
		wshremote.RunSysInfoLoop(client, connServerConnName)
	}()
	startJobLogCleanup()
	log.Printf("running server, successfully started")
	select {}
}

func serverRunRouterDomainSocket(jwtToken string) error {
	log.Printf("starting connserver router (domain socket upstream)")

	// extract socket name from JWT token (unverified - we're on the client side)
	sockName, err := wshutil.ExtractUnverifiedSocketName(jwtToken)
	if err != nil {
		return fmt.Errorf("error extracting socket name from JWT: %v", err)
	}

	// connect to the forwarded domain socket
	sockName = wavebase.ExpandHomeDirSafe(sockName)
	conn, err := net.Dial("unix", sockName)
	if err != nil {
		return fmt.Errorf("error connecting to domain socket %s: %v", sockName, err)
	}

	// create router
	router := wshutil.NewWshRouter()
	ConnServerWshRouter = router

	// create proxy for the domain socket connection
	upstreamProxy := wshutil.MakeRpcProxy("connserver-upstream")

	// goroutine to write to the domain socket
	go func() {

View on GitHub (pinned to a4447c1563)

Solutions

  1. Re-obtain the JWT from the Wave terminal environment (restart `wsh` from inside a Wave block) rather than reusing a stored value.
  2. Check the token is a complete 3-part JWT and not truncated (echo "$WAVETERM_CONNSERVER_JWT" style).
  3. Inspect the unverified payload (echo <token> | cut -d. -f2 | base64 -d) to confirm the socket-name claim exists.
  4. Ensure wsh and server versions match so the claim name is the expected one.
Defensive patterns

Strategy: validation

Validate before calling

func looksLikeJwt(tok string) bool {
	parts := strings.Split(tok, ".")
	if len(parts) != 3 { return false }
	for _, p := range parts {
		if _, err := base64.RawURLEncoding.DecodeString(p); err != nil { return false }
	}
	return true
}
// call before serverRunRouterDomainSocket:
if !looksLikeJwt(jwtToken) { return errors.New("malformed jwt token") }

Type guard

func hasSocketNameClaim(tok string) bool {
	parts := strings.Split(tok, ".")
	if len(parts) != 3 { return false }
	raw, err := base64.RawURLEncoding.DecodeString(parts[1])
	if err != nil { return false }
	var claims map[string]any
	if json.Unmarshal(raw, &claims) != nil { return false }
	_, ok := claims["socketname"]
	return ok
}

Try / catch

sockName, err := wshutil.ExtractUnverifiedSocketName(jwtToken)
if err != nil {
	return fmt.Errorf("error extracting socket name from JWT: %w", err)
}

Prevention

When it happens

Trigger: Calling serverRunRouterDomainSocket with a jwtToken whose payload does not contain the expected socket-name claim, or that fails base64/JSON parsing of the unverified claims section.

Common situations: Passing an arbitrary/stale environment variable instead of the token Wave injects (e.g. WAVETERM_CLIENTJWT variants); token truncated by shell quoting; using a token from a different Wave version with a changed claim name; hand-constructing the JWT.

Related errors


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