{"record":{"id":"763f18d1dcec7efb","repo":"apache/seatunnel","slug":"close-failed","errorCode":"CLOSE_FAILED","errorMessage":"Failed to close SNMP SET client for agent {host}:{port}","messagePattern":"Failed to close SNMP SET client for agent (.+?):(.+?)","errorType":"error_code","errorClass":"SnmpConnectorException","httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-snmp/src/main/java/org/apache/seatunnel/connectors/seatunnel/snmp/sink/SnmpSinkWriter.java","lineNumber":80,"sourceCode":"        } catch (IOException e) {\n            throw new SnmpConnectorException(\n                    SnmpConnectorErrorCode.WRITE_FAILED,\n                    \"Failed to set OID \"\n                            + request.getOid()\n                            + \" on SNMP agent \"\n                            + config.getHost()\n                            + \":\"\n                            + config.getPort(),\n                    e);\n        }\n    }\n\n    @Override\n    public void close() {\n        try {\n            client.close();\n        } catch (IOException e) {\n            throw new SnmpConnectorException(\n                    SnmpConnectorErrorCode.CLOSE_FAILED,\n                    \"Failed to close SNMP SET client for agent \"\n                            + config.getHost()\n                            + \":\"\n                            + config.getPort(),\n                    e);\n        }\n    }\n\n    interface SnmpSetClientFactory {\n        SnmpSetClient create(SnmpSinkConfig config) throws IOException;\n    }\n}\n","sourceCodeStart":62,"sourceCodeEnd":94,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-snmp/src/main/java/org/apache/seatunnel/connectors/seatunnel/snmp/sink/SnmpSinkWriter.java#L62-L94","documentation":"SnmpSinkWriter.close() releases the SNMP client; if client.close() throws IOException, it is rethrown as SnmpConnectorException with CLOSE_FAILED. The underlying SNMP session (transport listener) could not be shut down cleanly during task cleanup.","triggerScenarios":"Calling close() on SnmpSinkWriter when the delegated Snmp4jSetClient.close() (SNMP4J snmp.close()) throws IOException — transport already broken or socket already closed.","commonSituations":"Agent/network died before close so the UDP transport is in an error state; close called twice (double lifecycle invocation); JVM teardown racing with the close; test harness closing the client repeatedly.","solutions":["Check the wrapped cause; if it is 'socket already closed' style, the failure is benign and lifecycle bookkeeping should prevent double close.","Ensure close() is invoked once per writer lifecycle (avoid calling after task teardown).","Log-and-continue may be appropriate for close failures since data already written cannot be undone by a retry.","Verify no other thread is using the client concurrently while close runs.","If persistent, restart the worker to reclaim transport resources."],"exampleFix":"// before\nwriter.close();\nwriter.close(); // second call fails\n// after\nif (!writerClosed) { writer.close(); writerClosed = true; }","handlingStrategy":"fallback","validationCode":"if (!writerClosed) { /* safe to close */ }","typeGuard":null,"tryCatchPattern":"try {\n    writer.close();\n} catch (SnmpConnectorException e) {\n    LOG.warn(\"SNMP sink close failed for {}:{} (data already flushed)\", config.getHost(), config.getPort(), e);\n}","preventionTips":["Invoke close exactly once per writer lifecycle.","Treat close failures as non-fatal: log and continue, since data was already sent.","Avoid concurrent use of the client while closing.","In tests, use @AfterAll-style single teardown to prevent repeated closes."],"tags":["snmp","cleanup","close","sink"],"backgroundTag":"invalid-state-transition","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"}