Eugeny/tabby · error · Error

Remote rejected opening a shell channel: ${err}

Error message

Remote rejected opening a shell channel: ${err}

What it means

Thrown by SSHShell when `ssh.openShellChannel({ x11 })` rejects - the remote SSH server refused to open an interactive shell channel. The original error is wrapped with a descriptive prefix; if the underlying error mentions X11, the user is additionally hinted to install `xauth` on the remote. Common when the server limits channels, the user has no shell, or pty allocation is denied.

Source

Thrown at tabby-ssh/src/session/shell.ts:48

    async start (): Promise<void> {
        if (!this.ssh) {
            throw new Error('SSH session not set')
        }

        this.ssh.ref()
        this.ssh.willDestroy$.subscribe(() => {
            this.destroy()
        })

        this.logger.debug('Opening shell')

        try {
            this.shell = await this.ssh.openShellChannel({ x11: this.profile.options.x11 })
        } catch (err) {
            if (err.toString().includes('Unable to request X11')) {
                this.emitServiceMessage('    Make sure `xauth` is installed on the remote side')
            }
            throw new Error(`Remote rejected opening a shell channel: ${err}`)
        }

        this.open = true
        this.logger.debug('Shell open')

        this.loginScriptProcessor?.executeUnconditionalScripts()

        this.shell.data$.subscribe(data => {
            this.emitOutput(Buffer.from(data))
        })

        this.shell.eof$.subscribe(() => {
            this.logger.info('Shell session ended')
            if (this.open) {
                this.destroy()
            }
        })
    }

View on GitHub (pinned to 14e2d60b9b)

Solutions

  1. Reduce concurrent sessions on that host or raise server `MaxSessions`/`MaxStartups` if you administer it.
  2. For an X11-related rejection, install `xauth` on the remote and enable `X11Forwarding yes`, or disable X11 in the profile (`options.x11 = false`).
  3. Confirm the account has a valid shell (`/bin/bash`, not `/usr/sbin/nologin`) and `PermitTTY yes`.
  4. Catch the error and retry once for transient transport drops; surface the wrapped remote message to the user for server-side fixes.

Example fix

// before
try { this.shell = await this.ssh.openShellChannel({ x11: this.profile.options.x11 }) }
catch (err) { throw new Error(`Remote rejected opening a shell channel: ${err}`) }

// after - retry without X11 if X11 was the cause
try {
    this.shell = await this.ssh.openShellChannel({ x11: this.profile.options.x11 })
} catch (err) {
    if (this.profile.options.x11 && err.toString().includes('X11')) {
        this.shell = await this.ssh.openShellChannel({ x11: false })
    } else throw new Error(`Remote rejected opening a shell channel: ${err}`)
}
Defensive patterns

Strategy: retry

Validate before calling

function shouldRequestX11 (profile: SSHProfile, serverSupportsX11: boolean): boolean {
    return Boolean(profile.options.x11) && serverSupportsX11
}

Try / catch

try {
    this.shell = await this.ssh.openShellChannel({ x11: this.profile.options.x11 })
} catch (err) {
    const msg = err.toString()
    if (this.profile.options.x11 && /X11/i.test(msg)) {
        // retry without X11; server denied forwarding
        this.shell = await this.ssh.openShellChannel({ x11: false })
    } else {
        throw new Error(`Remote rejected opening a shell channel: ${err}`)
    }
}

Prevention

When it happens

Trigger: Calling `openShellChannel` against a server that rejects channel open: server-side `MaxSessions`/`MaxStartups` exceeded, the account has `nologin`/no shell, pty allocation denied by `sshd_config` (`PermitTTY no`), X11 forwarding requested but `X11Forwarding no` on the server, or the connection dropped mid-handshake.

Common situations: Reached per-user/session limit on a busy bastion; SFTP-only account used for a shell tab; X11 forwarding enabled in the profile but disabled on the server; flaky network caused the transport to die right before channel open.

Related errors


AI-assisted analysis of Eugeny/tabby@14e2d60b9b (2026-08-12). Data as JSON: /api/errors/c874f702d72fdc68. Report an issue: GitHub.