Eugeny/tabby · error · Error
Cannot add remote port forward before auth
Error message
Cannot add remote port forward before auth
What it means
Thrown by addPortForward() when forwarding type is Remote (server-side -R forward) but this.ssh is not yet an AuthenticatedSSHClient. Remote forwards require the authenticated transport to call forwardTCPPort on the server, so an unauthenticated session cannot set one up.
Source
Thrown at tabby-ssh/src/session/ssh.ts:818
}).catch(err => {
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote has rejected the forwarded connection to ${targetAddress}:${targetPort} via ${fw}: ${err}`)
reject()
throw err
}))
const socket = accept()
this.setupSocketChannelEvents(channel, socket, 'Local forward')
}).then(() => {
this.emitServiceMessage(colors.bgGreen.black(' -> ') + ` Forwarded ${fw}`)
this.forwardedPorts.push(fw)
}).catch(e => {
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Failed to forward port ${fw}: ${e}`)
throw e
})
}
if (fw.type === PortForwardType.Remote) {
if (!(this.ssh instanceof russh.AuthenticatedSSHClient)) {
throw new Error('Cannot add remote port forward before auth')
}
try {
await this.ssh.forwardTCPPort(fw.host, fw.port)
} catch (err) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote rejected port forwarding for ${fw}: ${err}`)
return
}
this.emitServiceMessage(colors.bgGreen.black(' <- ') + ` Forwarded ${fw}`)
this.forwardedPorts.push(fw)
}
}
async removePortForward (fw: ForwardedPort): Promise<void> {
if (fw.type === PortForwardType.Local || fw.type === PortForwardType.Dynamic) {
fw.stopLocalListener()
this.forwardedPorts = this.forwardedPorts.filter(x => x !== fw)
}View on GitHub (pinned to 14e2d60b9b)
Solutions
- Ensure the session is fully started and authenticated (await session.start()) before calling addPortForward for a Remote forward.
- Gate the call on the instance check: only add the remote forward once this.ssh instanceof russh.AuthenticatedSSHClient.
- Configure remote forwards via profile.options.forwardedPorts so they are applied after auth success at ssh.ts:493, not before.
- If the session lost auth mid-flight, re-establish it before retrying the forward.
Example fix
// before
session.addPortForward(remoteFw) // may run before auth
// after
await session.start()
if (session.ssh instanceof russh.AuthenticatedSSHClient) {
await session.addPortForward(remoteFw)
} Defensive patterns
Strategy: type-guard
Validate before calling
import * as russh from 'russh'
if (fw.type === PortForwardType.Remote &&
!(session.ssh instanceof russh.AuthenticatedSSHClient)) {
throw new Error('Wait for SSH auth before adding a remote port forward')
} Type guard
import * as russh from 'russh'
function isAuthed (s: unknown): s is russh.AuthenticatedSSHClient {
return s instanceof russh.AuthenticatedSSHClient
} Prevention
- Await session.start() before adding remote forwards programmatically.
- Prefer declaring remote forwards in profile.options.forwardedPorts so they apply post-auth.
- Never call addPortForward from a pre-auth or disconnect handler.
When it happens
Trigger: addPortForward(fw) called with fw.type === PortForwardType.Remote while this.ssh is still a plain russh.SSHClient (pre-auth) or has been disconnected. Can occur if a profile's options.forwardedPorts are applied before auth completes, or if a caller invokes addPortForward manually right after constructing the session.
Common situations: Programmatic use that adds a Remote forward before awaiting the session start/auth; a race where addPortForward runs during reconnection before re-auth finishes; profile with remote forwards loaded into a session whose auth subsequently failed but the forward list is still being applied.
Related errors
- Cannot remove remote port forward before auth
- Cannot open shell channel before auth
- Authentication rejected
- Download cancelled
- ${profile.options.host}: jump host "${profile.options.jumpHo
AI-assisted analysis of Eugeny/tabby@14e2d60b9b (2026-08-12).
Data as JSON: /api/errors/a927981ac683a2ad.
Report an issue: GitHub.