{"record":{"id":"0a5f3432335705a8","repo":"apache/seatunnel","slug":"failed-to-close-arrow-stream-reader","errorCode":null,"errorMessage":"failed to close arrow stream reader.","messagePattern":"failed to close arrow stream reader\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-common/src/main/java/org/apache/seatunnel/connectors/seatunnel/common/source/arrow/reader/ArrowToSeatunnelRowReader.java","lineNumber":333,"sourceCode":"            }\n            return convertSeatunnelRowValue(dataType.getSqlType(), null, value);\n        };\n    }\n\n    @Override\n    public void close() {\n        try {\n            if (root != null) {\n                root.close();\n            }\n            if (rootAllocator != null) {\n                rootAllocator.close();\n            }\n            if (arrowStreamReader != null) {\n                arrowStreamReader.close();\n            }\n        } catch (IOException e) {\n            throw new RuntimeException(\"failed to close arrow stream reader.\", e);\n        }\n    }\n}\n","sourceCodeStart":315,"sourceCodeEnd":337,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-common/src/main/java/org/apache/seatunnel/connectors/seatunnel/common/source/arrow/reader/ArrowToSeatunnelRowReader.java#L315-L337","documentation":"ArrowToSeatunnelRowReader.close() releases the Arrow RootAllocator and closes the ArrowStreamReader. If closing the underlying Arrow stream reader raises an IOException, the method wraps it in this RuntimeException with the original IOException as cause. This fires during teardown, so it often masks or follows an earlier read failure.","triggerScenarios":"Calling close() on an ArrowToSeatunnelRowReader whose underlying ArrowStreamReader.close() throws IOException, e.g. when the input stream is already corrupted/closed or the read side errored earlier. RootAllocator close must also have succeeded for the reader close branch to run.","commonSituations":"Arrow file/stream truncated on disk or in network transfer; reader closed after a prior read exception; filesystem (HDFS/S3) connection dropped mid-stream; closing reader twice in custom source code.","solutions":["Inspect the cause (getCause()) IOException — fix the underlying stream/IO problem (e.g. file truncation, connection drop) rather than treating this as the root error","Verify the Arrow stream file is complete and readable (check size/checksum) before reading","Avoid calling close() more than once on the reader; guard with a closed flag","Ensure the reader is closed only after reads finish or after handling read exceptions so the cause reflects the real failure"],"exampleFix":"// before\nreader.close(); // throws RuntimeException('failed to close arrow stream reader.')\n// after\ntry {\n    reader.close();\n} catch (RuntimeException e) {\n    LOG.warn(\"arrow reader close failed\", e.getCause());\n}","handlingStrategy":"try-catch","validationCode":"// verify stream before constructing reader\nFile f = new File(arrowPath);\nif (!f.exists() || f.length() == 0) throw new IllegalStateException(\"arrow stream missing/empty: \" + arrowPath);","typeGuard":null,"tryCatchPattern":"try {\n    reader.close();\n} catch (RuntimeException e) {\n    LOG.warn(\"failed to close arrow stream reader\", e.getCause());\n}","preventionTips":["Close the reader exactly once, guarded by a boolean flag","Always close via try-with-resources or finally so allocator leaks don't compound failures","Check file/stream integrity (size, checksum) before reading Arrow streams","Log the cause, not just the wrapper, when diagnosing close failures"],"tags":["arrow","io","resource-cleanup","source-connector"],"backgroundTag":"file-read-failed","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"}