{"record":{"id":"cbb39c15b4edb8ce","repo":"apache/seatunnel","slug":"iotdbconnectorerrorcode-close-session-failed-cbb39c","errorCode":"IotdbConnectorErrorCode.CLOSE_SESSION_FAILED","errorMessage":"Close IoTDB session failed","messagePattern":"Close IoTDB session failed","errorType":"error_code","errorClass":"IotdbConnectorException","httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-iotdb-v2/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdbv2/source/relational/IoTDBv2RelationalSourceReader.java","lineNumber":71,"sourceCode":"    public IoTDBv2RelationalSourceReader(\n            ReadonlyConfig conf, SourceReader.Context readerContext, SeaTunnelRowType rowType) {\n        super(conf, readerContext);\n        this.deserializer = new DefaultSeaTunnelRowDeserializer(rowType, SourceConstants.TABLE);\n    }\n\n    @Override\n    public void open() throws Exception {\n        tableSession = buildTableSession(conf);\n    }\n\n    @Override\n    public void close() throws IOException {\n        try {\n            if (tableSession != null) {\n                tableSession.close();\n            }\n        } catch (IoTDBConnectionException e) {\n            throw new IotdbConnectorException(\n                    IotdbConnectorErrorCode.CLOSE_SESSION_FAILED, \"Close IoTDB session failed\", e);\n        }\n    }\n\n    private ITableSession buildTableSession(ReadonlyConfig conf) throws IoTDBConnectionException {\n        TableSessionBuilder sessionBuilder = new TableSessionBuilder().enableCompression(false);\n        List<String> nodes = conf.get(NODE_URLS);\n        sessionBuilder.nodeUrls(nodes);\n        if (null != conf.get(FETCH_SIZE)) {\n            sessionBuilder.fetchSize(Integer.parseInt(conf.get(FETCH_SIZE).toString()));\n        }\n        if (null != conf.get(USERNAME)) {\n            sessionBuilder.username(conf.get(USERNAME));\n        }\n        if (null != conf.get(PASSWORD)) {\n            sessionBuilder.password(conf.get(PASSWORD));\n        }\n        if (null != conf.get(DATABASE)) {","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-iotdb-v2/src/main/java/org/apache/seatunnel/connectors/seatunnel/iotdbv2/source/relational/IoTDBv2RelationalSourceReader.java#L53-L89","documentation":"This error is thrown by IoTDBv2RelationalSourceReader.close() when the TableSession cannot be closed cleanly, i.e. tableSession.close() raises IoTDBConnectionException. It wraps the original exception with error code CLOSE_SESSION_FAILED. It usually indicates the connection to the IoTDB server was already broken (network drop, server restart, session timeout) rather than a problem with close() itself.","triggerScenarios":"Calling close() on the source reader while tableSession != null and tableSession.close() throws IoTDBConnectionException — typically after the IoTDB server became unreachable, the session was already closed server-side, or a network partition occurred.","commonSituations":"IoTDB cluster restarted or failed over mid-job; idle session reaped by server timeout; firewall/NAT dropped the long-lived TCP connection during a long-running read; DNS/network change in Kubernetes environments.","solutions":["Check IoTDB server logs and availability at the time close() was called; the underlying cause is usually a broken connection, not close logic","Verify network stability between the SeaTunnel worker and the IoTDB node(s) (firewall idle-connection timeouts, keepalive settings)","Tune IoTDB session timeouts (e.g. enable_rpc_compression / session idle timeout) so idle sessions are not reaped during long reads","If transient, retry the job; ensure the reader's close failure does not mask the original read error by inspecting the wrapped cause"],"exampleFix":"// before\ntry {\n    if (tableSession != null) {\n        tableSession.close();\n    }\n} catch (IoTDBConnectionException e) {\n    throw new IotdbConnectorException(IotdbConnectorErrorCode.CLOSE_SESSION_FAILED, \"Close IoTDB session failed\", e);\n}\n// after\ntry {\n    if (tableSession != null) {\n        tableSession.close();\n    }\n} catch (IoTDBConnectionException e) {\n    log.warn(\"IoTDB session already broken during close; cause: {}\", e.getMessage());\n    throw new IotdbConnectorException(IotdbConnectorErrorCode.CLOSE_SESSION_FAILED, \"Close IoTDB session failed\", e);\n}","handlingStrategy":"try-catch","validationCode":"// pre-check before job\nProcess p = Runtime.getRuntime().exec(new String[]{\"/bin/sh\",\"-c\",\"nc -z -w 3 <iotdb-host> 6667 && echo OK || echo FAIL\"});\n// p.waitFor() output should be OK","typeGuard":"boolean sessionOpen(TableSession s) { return s != null; }","tryCatchPattern":"try { reader.close(); } catch (IotdbConnectorException e) {\n    if (e.getCode() == IotdbConnectorErrorCode.CLOSE_SESSION_FAILED) {\n        log.warn(\"IoTDB session close failed (likely already broken): {}\", e.getCause());\n    } else { throw e; }\n}","preventionTips":["Monitor IoTDB cluster health before and during jobs","Avoid long idle periods that trigger server-side session timeouts","Keep the connector's IoTDB client version aligned with the server version"],"tags":["iotdb","session-close","network"],"backgroundTag":"connection-refused","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}