{"record":{"id":"441f727eb12c6e29","repo":"apache/dolphinscheduler","slug":"ssh-connection-failed","errorCode":null,"errorMessage":"SSH connection failed","messagePattern":"SSH connection failed","errorType":"exception","errorClass":"TaskException","httpStatus":null,"severity":"critical","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-remoteshell/src/main/java/org/apache/dolphinscheduler/plugin/task/remoteshell/RemoteExecutor.java","lineNumber":84,"sourceCode":"    public RemoteExecutor(SSHConnectionParam sshConnectionParam) {\n\n        this.sshConnectionParam = sshConnectionParam;\n        initClient();\n    }\n\n    private void initClient() {\n        sshClient = SshClient.setUpDefaultClient();\n        sshClient.start();\n    }\n\n    private ClientSession getSession() {\n        if (session != null && session.isOpen()) {\n            return session;\n        }\n        try {\n            session = SSHUtils.getSession(sshClient, sshConnectionParam);\n            if (session == null || !session.auth().verify().isSuccess()) {\n                throw new TaskException(\"SSH connection failed\");\n            }\n        } catch (Exception e) {\n            throw new TaskException(\"SSH connection failed\", e);\n        }\n        return session;\n    }\n\n    public int run(String taskId, String localFile) throws IOException {\n        try {\n            // only run task if no exist same task\n            String pid = getTaskPid(taskId);\n            if (StringUtils.isEmpty(pid)) {\n                saveCommand(taskId, localFile);\n                String runCommand = String.format(COMMAND.RUN_COMMAND, getRemoteShellHome(), taskId,\n                        getRemoteShellHome(), taskId);\n                runRemote(runCommand);\n            }\n            track(taskId);","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-remoteshell/src/main/java/org/apache/dolphinscheduler/plugin/task/remoteshell/RemoteExecutor.java#L66-L102","documentation":"RemoteExecutor.getSession establishes an SSH session via SSHUtils.getSession; if the returned session is null or SSH authentication (session.auth().verify()) does not succeed, it throws TaskException(\"SSH connection failed\") with no cause. This is the explicit no-cause variant indicating connection setup or auth verification failed.","triggerScenarios":"uploadScript() or runRemoteAndProcessLines() call getSession() and either SSHUtils.getSession returns null (connection could not be established) or the SSH auth result is not isSuccess().","commonSituations":"Wrong host/port in remote shell task params; wrong username/password or private key; SSH server rejects the auth method (password auth disabled); network/firewall blocking port 22; host key rejection.","solutions":["Test SSH connectivity manually from the worker host: ssh <user>@<host> -p <port> using the same credentials/key.","Verify the RemoteShellParameters connection params (host, port, user, password/privateKey) are correct and complete.","If using a private key, confirm the key format is supported (OpenSSH vs PEM) and has no passphrase unless configured.","Check the SSH server config (sshd_config) for PasswordAuthentication/PublicKeyAuthentication settings matching your auth method.","Confirm firewall/network policy allows the worker to reach the target on the SSH port."],"exampleFix":"// before (no detail about which check failed)\nif (session == null || !session.auth().verify().isSuccess()) {\n    throw new TaskException(\"SSH connection failed\");\n}\n// after (distinguish null vs auth failure)\nif (session == null) {\n    throw new TaskException(\"SSH connection failed: could not connect to \" + sshConnectionParam.getHost());\n}\nif (!session.auth().verify().isSuccess()) {\n    throw new TaskException(\"SSH authentication failed for user \" + sshConnectionParam.getUser());\n}","handlingStrategy":"validation","validationCode":"// pre-flight from the worker host\nboolean reachable = new Socket().connect(new InetSocketAddress(host, port), 5000);\n// and: ssh -o BatchMode=yes -i keyfile user@host 'echo ok' must succeed","typeGuard":"boolean validSshParam(RemoteShellParameters p) {\n    return p != null && notBlank(p.getHost()) && p.getPort() > 0 && notBlank(p.getUser())\n        && (notBlank(p.getPassword()) || notBlank(p.getPrivateKey()));\n}","tryCatchPattern":"try {\n    remoteExecutor.run(taskId, script);\n} catch (TaskException e) {\n    if (e.getMessage().contains(\"SSH connection failed\")) {\n        logger.error(\"SSH setup/auth failure — verify host, port, credentials\");\n    }\n    throw e;\n}","preventionTips":["Store SSH credentials/keys in DolphinScheduler's resource center or env files, not inline in workflows.","Run a BatchMode ssh pre-flight check on worker startup for configured remote hosts.","Ensure the SSH server allows the chosen auth method (password vs publickey)."],"tags":["ssh","network","authentication","remote-execution"],"backgroundTag":"authentication-required","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}