getredash/redash · error · NotImplementedError

SSH tunneling is not implemented for this query runner yet.

Error message

SSH tunneling is not implemented for this query runner yet.

What it means

The @tunnel decorator raises NotImplementedError when accessing query_runner.host or query_runner.port itself raised NotImplementedError — the runner doesn't expose host/port, so an SSH bastion tunnel cannot be constructed for it.

Source

Thrown at redash/query_runner/__init__.py:498

        return TYPE_BOOLEAN

    try:
        parser.parse(string_value)
        return TYPE_DATETIME
    except (ValueError, OverflowError):
        pass

    return TYPE_STRING


def with_ssh_tunnel(query_runner, details):
    def tunnel(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            try:
                remote_host, remote_port = query_runner.host, query_runner.port
            except NotImplementedError:
                raise NotImplementedError("SSH tunneling is not implemented for this query runner yet.")

            stack = ExitStack()
            try:
                bastion_address = (details["ssh_host"], details.get("ssh_port", 22))
                remote_address = (remote_host, remote_port)
                auth = {
                    "ssh_username": details["ssh_username"],
                    **settings.dynamic_settings.ssh_tunnel_auth(),
                }
                server = stack.enter_context(open_tunnel(bastion_address, remote_bind_address=remote_address, **auth))
            except Exception as error:
                raise type(error)("SSH tunnel: {}".format(str(error)))

            with stack:
                try:
                    query_runner.host, query_runner.port = server.local_bind_address
                    result = f(*args, **kwargs)
                finally:

View on GitHub (pinned to ca79fe988d)

Solutions

  1. Disable the SSH tunnel option on that data source
  2. Use a query runner type that implements host/port (a SQL driver runner) if tunneling is required
  3. Run an external tunnel (ssh -L) and point the data source at localhost

Example fix

# before (data source options)
{"ssh_tunnel_enabled": true, "ssh_host": "bastion"}

# after
{"ssh_tunnel_enabled": false, "host": "127.0.0.1", "port": 5432}  # via ssh -L 5432:db:5432 bastion
Defensive patterns

Strategy: validation

Validate before calling

if details.get('ssh_host'):
    try:
        _ = (query_runner.host, query_runner.port)
    except NotImplementedError:
        raise SystemExit('this runner type does not support SSH tunnels')

Type guard

def supports_tunnel(runner) -> bool:
    try:
        _ = (runner.host, runner.port); return True
    except NotImplementedError:
        return False

Try / catch

try:
    result = runner.run_query(q, u)
except NotImplementedError as e:
    if 'SSH tunneling' in str(e):
        disable_tunnel_and_point_at_local_forward(); retry

Prevention

When it happens

Trigger: Enabling 'Use SSH tunnel' (ssh_host set in data source options) on a query runner whose class does not implement the host/port properties, which raise NotImplementedError on BaseQueryRunner by design.

Common situations: Trying to tunnel an HTTP/API-type or other non-protocol runner, or enabling the tunnel checkbox on a runner where tunneling was never implemented.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of getredash/redash@ca79fe988d (2026-08-28). Data as JSON: /api/errors/b5769897533a40e3. Report an issue: GitHub.