henrygd/beszel · error

SSH disabled

Error message

SSH disabled

What it means

StartServer returns 'SSH disabled' when the DISABLE_SSH environment variable is set to 'true'. This allows running the agent purely in push/poll mode without its embedded SSH server. It is a deliberate configuration guard, not an unexpected failure.

Source

Thrown at agent/server.go:38

	"github.com/fxamacker/cbor/v2"
	"github.com/gliderlabs/ssh"
	gossh "golang.org/x/crypto/ssh"
)

// ServerOptions contains configuration options for starting the SSH server.
type ServerOptions struct {
	Addr    string            // Network address to listen on (e.g., ":45876" or "/path/to/socket")
	Network string            // Network type ("tcp" or "unix")
	Keys    []gossh.PublicKey // SSH public keys for authentication
}

// StartServer starts the SSH server with the provided options.
// It configures the server with secure defaults, sets up authentication,
// and begins listening for connections. Returns an error if the server
// is already running or if there's an issue starting the server.
func (a *Agent) StartServer(opts ServerOptions) error {
	if disableSSH, _ := utils.GetEnv("DISABLE_SSH"); disableSSH == "true" {
		return errors.New("SSH disabled")
	}
	if a.server != nil {
		return errors.New("server already started")
	}

	slog.Info("Starting SSH server", "addr", opts.Addr, "network", opts.Network)

	if opts.Network == "unix" {
		// remove existing socket file if it exists
		if err := os.Remove(opts.Addr); err != nil && !os.IsNotExist(err) {
			return err
		}
	}

	// start listening on the address
	ln, err := net.Listen(opts.Network, opts.Addr)
	if err != nil {
		return err

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Remove DISABLE_SSH=true from the agent's environment (env file, systemd unit, docker-compose) and restart
  2. If the hub uses WebSocket connection mode, configure the system in the hub accordingly so it doesn't need SSH
  3. Set DISABLE_SSH to any value other than 'true' (or unset it)

Example fix

// before (docker-compose)
environment:
  - DISABLE_SSH=true
// after
environment:
  - KEY=... # DISABLE_SSH removed
Defensive patterns

Strategy: validation

Validate before calling

// before starting the agent
if v, _ := utils.GetEnv("DISABLE_SSH"); v == "true" && hubUsesSSHConnection {
    log.Fatal("hub connects via SSH but DISABLE_SSH=true")
}

Try / catch

if err := agent.StartServer(opts); err != nil {
    if err.Error() == "SSH disabled" {
        log.Info("SSH intentionally disabled; running in push mode")
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Agent.StartServer is called while the environment contains DISABLE_SSH=true; the check runs before any socket binding, so it fires immediately on startup.

Common situations: Operator intentionally disabled the SSH server for security hardening but the hub is still configured to connect to the agent over SSH; a stale DISABLE_SSH=true left in a container env or systemd unit after switching connection modes.

Related errors


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