henrygd/beszel · error

failed to decode response

Error message

failed to decode response: %w

What it means

In transport.SSH Request (internal/hub/transport/ssh.go:108), after sending the request the hub CBOR-decodes the agent's reply from stdout into common.AgentResponse; failure is wrapped as 'failed to decode response'. Typically the stream ended (EOF) or returned non-CBOR output because the agent died or sshd emitted text instead of protocol data.

Solutions

  1. Check the agent is installed, executable and running on the remote host (systemctl status beszel-agent)
  2. Remove anything printing to stdout in remote shell init files (.bashrc/.profile) for the SSH user
  3. Read the wrapped cause: io.EOF means the agent closed the stream; cbor errors mean corrupted/garbage output
  4. Upgrade the agent to a version compatible with the hub (0.19+ for generic Data responses)
Defensive patterns

Strategy: retry

Validate before calling

out, err := sshClient.Output("command -v beszel-agent || echo MISSING")
if strings.TrimSpace(out) == "MISSING" {
    return errors.New("agent binary not installed on remote host")
}

Try / catch

err := t.Request(ctx, action, req, dest)
if err != nil && strings.Contains(err.Error(), "failed to decode response") {
    if errors.Is(err, io.EOF) {
        return retryAfterReconnect(ctx, action, req, dest) // agent died mid-request
    }
    return err // garbage output; inspect agent env
}

Prevention

When it happens

Trigger: Agent process exits before replying (stdout EOF); agent prints plain text/errors to stdout (login banners, shell init scripts, missing binary) contaminating the CBOR stream; truncated response when the session is closed early.

Common situations: Remote ~/.bashrc or /etc/profile echoing text on non-interactive SSH sessions; agent binary missing/not executable so sshd returns an error message; agent OOM-killed mid-request; agent version too old to speak the expected protocol.

Understand the failure class

Related errors


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/e9021e25e59fa88f. Report an issue: GitHub.

Appendix: source

Thrown at internal/hub/transport/ssh.go:108

	stdin, err := session.StdinPipe()
	if err != nil {
		return err
	}
	if err := session.Shell(); err != nil {
		return err
	}

	// Send request
	hubReq := common.HubRequest[any]{Action: action, Data: req}
	if err := cbor.NewEncoder(stdin).Encode(hubReq); err != nil {
		return fmt.Errorf("failed to encode request: %w", err)
	}
	stdin.Close()

	// Read response
	var resp common.AgentResponse
	if err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {
		return fmt.Errorf("failed to decode response: %w", err)
	}

	if resp.Error != "" {
		return errors.New(resp.Error)
	}

	if err := session.Wait(); err != nil {
		return err
	}

	return UnmarshalResponse(resp, action, dest)
}

// IsConnected returns true if the SSH connection is active.
func (t *SSHTransport) IsConnected() bool {
	return t.client != nil
}

View on GitHub (pinned to b38fb7dafa)