{"record":{"id":"d9041c2ff8a09e42","repo":"apache/flink","slug":"could-not-close-resource","errorCode":null,"errorMessage":"Could not close resource.","messagePattern":"Could not close resource\\.","errorType":"exception","errorClass":"FlinkException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/util/AutoCloseableAsync.java","lineNumber":38,"sourceCode":"\nimport java.util.concurrent.CompletableFuture;\nimport java.util.concurrent.ExecutionException;\n\n/** Closeable interface which allows to close a resource in a non blocking fashion. */\npublic interface AutoCloseableAsync extends AutoCloseable {\n\n    /**\n     * Trigger the closing of the resource and return the corresponding close future.\n     *\n     * @return Future which is completed once the resource has been closed\n     */\n    CompletableFuture<Void> closeAsync();\n\n    default void close() throws Exception {\n        try {\n            closeAsync().get();\n        } catch (ExecutionException e) {\n            throw new FlinkException(\n                    \"Could not close resource.\", ExceptionUtils.stripExecutionException(e));\n        }\n    }\n}\n","sourceCodeStart":20,"sourceCodeEnd":43,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/util/AutoCloseableAsync.java#L20-L43","documentation":"Thrown by the default close() method of AutoCloseableAsync when the CompletableFuture returned by closeAsync() completes exceptionally. The synchronous close() simply blocks on the async close and re-wraps the cause (with ExecutionException stripped) in a FlinkException.","triggerScenarios":"Calling close() on components implementing AutoCloseableAsync (common in flink-runtime: JobManager services, metric registries, HA services, blob server) when their async shutdown hook fails — e.g. a ZooKeeper connection error during HA service stop, or an RPC endpoint termination failure.","commonSituations":"Shutting down a mini-cluster or test harness while a dependent service (ZK, blob storage, RPC) is already broken; teardown during a failing test where the original failure surfaces only during close; double-closing a resource whose second close fails.","solutions":["Inspect the suppressed cause (e.getCause()) — the real failure is the underlying closeAsync future's exception, not this message","Fix the root cause in the async shutdown path (connection, timeout, state) that made the future fail","In tests and teardown code, catch and log close failures separately so they do not mask the original error (or use SuppressedExceptions/Closeable#quiet close utilities)"],"exampleFix":"// before\nresource.close(); // secondary failure hides the primary test failure\n\n// after\ntry {\n    resource.close();\n} catch (Exception e) {\n    LOG.warn(\"Failed to close {}\", resource, e); // don't mask the original error\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { resource.close(); } catch (FlinkException e) { log cause e.getCause(); in tests, record as suppressed instead of rethrowing over the primary failure }","preventionTips":["Always log or suppress the cause chain — the real failure is inside closeAsync's future","In teardown code, close resources best-effort so a secondary close failure never masks the primary exception"],"tags":["flink-core","lifecycle","async","shutdown","resource-management"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}