{"record":{"id":"61ace7ce0303ffaa","repo":"OtterMind/Chat2DB","slug":"connection-ssh-error","errorCode":"connection.ssh.error","errorMessage":"connection.ssh.error","messagePattern":"connection\\.ssh\\.error","errorType":"error_code","errorClass":"ConnectionException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDataSourceServiceImpl.java","lineNumber":102,"sourceCode":"    }\n\n    @Override\n    public DriverConfig defaultDriverConfig(String dbType) {\n        return Chat2DBContext.getDefaultDriverConfig(dbType);\n    }\n\n    @Override\n    public void removeConnection(Long id) {\n        ConnectionPool.removeConnection(id);\n    }\n\n    @Override\n    public void testSshConnection(SSHInfo ssh) {\n        Session session = null;\n        try {\n            session = SSHManager.getSSHSession(ssh);\n        } catch (Exception e) {\n            throw new ConnectionException(\"connection.ssh.error\", null, e);\n        } finally {\n            if (session != null) {\n                session.disconnect();\n            }\n        }\n    }\n\n    @Override\n    public void closeRuntime() {\n        Chat2DBContext.close();\n        SSHManager.close();\n    }\n\n    private void validate(DbDataSourcePreConnectRequest param) {\n        if (!ConfigUtils.isDesktop() && ConfigUtils.isRelease()) {\n            if (\"LocalFile\".equalsIgnoreCase(param.getServiceType())\n                    && (\"H2\".equalsIgnoreCase(param.getType()) || \"SQLite\".equalsIgnoreCase(param.getType()))) {\n                throw new BusinessException(\"web.not.support.db.type\");","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbDataSourceServiceImpl.java#L84-L120","documentation":"ConnectionException thrown by testSshConnection() when SSHManager.getSSHSession(ssh) raises any Exception (wrapped with the cause). It signals the SSH tunnel could not be established with the provided SSHInfo.","triggerScenarios":"testSshConnection(ssh) is called with an SSH host that is unreachable, wrong port, invalid credentials (password/key), key file unreadable, or the SSH server rejects authentication.","commonSituations":"Misconfigured SSH host/port, wrong username, expired/incorrect private key, key file permission issues on Linux, or the bastion host blocking the source IP.","solutions":["Inspect the chained cause for the SSH-layer error (auth failed, connection refused, timeout).","Verify SSH host, port, username, and that the private key path is readable and has correct permissions (chmod 600).","Confirm network reachability and firewall rules to the bastion before re-testing."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-flight SSH field check\nif (StringUtils.isAnyBlank(ssh.getHost(), ssh.getPort() == null ? null : String.valueOf(ssh.getPort()), ssh.getUserName())) {\n    return Result.fail(\"connection.ssh.error\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    dataSourceService.testSshConnection(ssh);\n} catch (ConnectionException e) {\n    // e.getCause() holds the SSH-layer error (auth/refused/timeout)\n    // prompt the user to fix host/port/user/key\n}","preventionTips":["Validate SSH host/port/user and key path before testing.","Ensure the private key file is readable with restrictive permissions (chmod 600).","Confirm bastion firewall rules allow the source IP."],"tags":["ssh","connection","tunnel","credentials"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}