wavetermdev/waveterm · error

unable to obtain remote info from connserver: %w

Error message

unable to obtain remote info from connserver: %w

What it means

The controller sends a RemoteGetInfoCommand RPC (2s timeout) to the remote connserver over the connection's wsh route to learn about the remote environment (e.g. which shell it runs). This error means that RPC failed — the remote wsh/connserver is unreachable, not installed, or too slow to respond.

Source

Thrown at pkg/blockcontroller/durableshellcontroller.go:248

		Cols: shellutil.DefaultTermCols,
	}
	if rtOpts != nil && rtOpts.TermSize.Rows > 0 && rtOpts.TermSize.Cols > 0 {
		termSize = rtOpts.TermSize
	}
	cmdStr := blockMeta.GetString(waveobj.MetaKey_Cmd, "")
	cwd := blockMeta.GetString(waveobj.MetaKey_CmdCwd, "")
	opts, err := remote.ParseOpts(connName)
	if err != nil {
		return "", fmt.Errorf("invalid ssh remote name (%s): %w", connName, err)
	}
	conn := conncontroller.MaybeGetConn(opts)
	if conn == nil {
		return "", fmt.Errorf("connection %q not found", connName)
	}
	connRoute := wshutil.MakeConnectionRouteId(connName)
	remoteInfo, err := wshclient.RemoteGetInfoCommand(wshclient.GetBareRpcClient(), &wshrpc.RpcOpts{Route: connRoute, Timeout: 2000})
	if err != nil {
		return "", fmt.Errorf("unable to obtain remote info from connserver: %w", err)
	}
	shellType := shellutil.GetShellTypeFromShellPath(remoteInfo.Shell)
	swapToken := makeSwapToken(ctx, ctx, dsc.BlockId, blockMeta, connName, shellType)
	sockName := wavebase.GetPersistentRemoteSockName(wstore.GetClientId())
	rpcContext := wshrpc.RpcContext{
		ProcRoute: true,
		SockName:  sockName,
		BlockId:   dsc.BlockId,
		Conn:      connName,
	}
	jwtStr, err := wshutil.MakeClientJWTToken(rpcContext)
	if err != nil {
		return "", fmt.Errorf("error making jwt token: %w", err)
	}
	swapToken.RpcContext = &rpcContext
	swapToken.Env[wshutil.WaveJwtTokenVarName] = jwtStr
	cmdOpts := shellexec.CommandOptsType{
		Interactive: true,

View on GitHub (pinned to a4447c1563)

Solutions

  1. Verify wsh is installed on the remote host and the connserver is running.
  2. Increase tolerance by retrying Start once the link is stable (timeout is hardcoded at 2000ms).
  3. Test basic SSH connectivity to the remote first.
  4. Reinstall/upgrade wsh on the remote if the version is incompatible.

Example fix

// before
err := controller.Start(ctx, blockMeta, rtOpts, false) // fails: connserver unreachable
// after
conn := conncontroller.MaybeGetConn(opts)
if conn.DeriveConnStatus().Status != conncontroller.Status_Connected {
    return fmt.Errorf("connect the remote before starting the shell")
}
err := controller.Start(ctx, blockMeta, rtOpts, false)
Defensive patterns

Strategy: retry

Validate before calling

connRoute := wshutil.MakeConnectionRouteId(connName)
if _, err := wshclient.RemoteGetInfoCommand(wshclient.GetBareRpcClient(), &wshrpc.RpcOpts{Route: connRoute, Timeout: 2000}); err != nil {
    return fmt.Errorf("remote connserver not reachable: %w", err)
}

Try / catch

err := controller.Start(ctx, meta, rtOpts, false)
if err != nil && strings.Contains(err.Error(), "connserver") {
    time.Sleep(time.Second) // brief backoff for slow links
    err = controller.Start(ctx, meta, rtOpts, false)
}

Prevention

When it happens

Trigger: RemoteGetInfoCommand returns an error: remote connserver not running, wsh not installed on the remote, network drop mid-handshake, or response exceeding the 2000ms timeout.

Common situations: First connection to a new remote where wsh hasn't been installed; slow VPN/high-latency link blowing the 2s timeout; remote daemon crashed; firewall blocking the wsh route.

Related errors


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