{"record":{"id":"03e90c7e778dc9d0","repo":"prestodb/presto","slug":"arrow-flight-info-error","errorCode":"ARROW_FLIGHT_INFO_ERROR","errorMessage":"Error getting flight information: ","messagePattern":"Error getting flight information: ","errorType":"error_code","errorClass":"ArrowException","httpStatus":null,"severity":"warning","filePath":"presto-base-arrow-flight/src/main/java/com/facebook/plugin/arrow/BaseArrowFlightClientHandler.java","lineNumber":139,"sourceCode":"                    clientKey.get().close();\n                }\n                catch (IOException e) {\n                    logger.error(\"Error closing input stream for client key\", e);\n                }\n            }\n        }\n    }\n\n    public abstract CallOption[] getCallOptions(ConnectorSession connectorSession);\n\n    protected FlightInfo getFlightInfo(ConnectorSession connectorSession, FlightDescriptor flightDescriptor)\n    {\n        try (FlightClient client = createFlightClient()) {\n            CallOption[] callOptions = getCallOptions(connectorSession);\n            return client.getInfo(flightDescriptor, callOptions);\n        }\n        catch (InterruptedException e) {\n            throw new ArrowException(ARROW_FLIGHT_INFO_ERROR, \"Error getting flight information: \" + e.getMessage(), e);\n        }\n    }\n\n    protected ClientClosingFlightStream getFlightStream(ConnectorSession connectorSession, ArrowSplit split)\n    {\n        ByteBuffer endpointBytes = ByteBuffer.wrap(split.getFlightEndpointBytes());\n        try {\n            FlightEndpoint endpoint = FlightEndpoint.deserialize(endpointBytes);\n            FlightClient client = endpoint.getLocations().stream()\n                    .findAny()\n                    .map(this::createFlightClient)\n                    .orElseGet(this::createFlightClient);\n            return new ClientClosingFlightStream(\n                    client.getStream(endpoint.getTicket(), getCallOptions(connectorSession)),\n                    client);\n        }\n        catch (FlightRuntimeException | IOException | URISyntaxException e) {\n            throw new ArrowException(ARROW_FLIGHT_CLIENT_ERROR, e.getMessage(), e);","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-base-arrow-flight/src/main/java/com/facebook/plugin/arrow/BaseArrowFlightClientHandler.java#L121-L157","documentation":"getFlightInfo issues a FlightClient.getInfo(descriptor, callOptions) RPC to resolve a descriptor into FlightInfo. The only checked exception is InterruptedException, which is wrapped as ArrowException(ARROW_FLIGHT_INFO_ERROR) with 'Error getting flight information: <msg>'. Note the catch does not restore the thread interrupt flag, so an interruption during this RPC surfaces as this connector error.","triggerScenarios":"Calling getFlightInfo (e.g. from getFlightInfoForTableScan) while the executing thread is interrupted — typically query cancellation, worker shutdown, or a thread pool being torn down mid-RPC.","commonSituations":"User cancels the Presto query while the driver thread is inside getInfo(); Presto worker shutdown/restart during query execution; session idle timeouts interrupting blocked RPC threads.","solutions":["Treat it as expected during query cancellation — rerun the query if cancellation was unintentional.","Avoid restarting/shutting down workers while queries are running (drain first).","If it happens spuriously under load, check for thread-pool exhaustion causing cancellation timers to fire late/incorrectly.","Ensure client code that wraps this call doesn't swallow interrupts and re-trigger.","Long-term: consider re-interrupting the thread before throwing to preserve cancellation semantics."],"exampleFix":"// before\ncatch (InterruptedException e) {\n    throw new ArrowException(ARROW_FLIGHT_INFO_ERROR, \"Error getting flight information: \" + e.getMessage(), e);\n}\n// after\ncatch (InterruptedException e) {\n    Thread.currentThread().interrupt();\n    throw new ArrowException(ARROW_FLIGHT_INFO_ERROR, \"Error getting flight information: \" + e.getMessage(), e);\n}","handlingStrategy":"retry","validationCode":"// Skip the RPC if the current thread is already interrupted\nif (Thread.currentThread().isInterrupted()) {\n    throw new IllegalStateException(\"Thread already interrupted; not calling getInfo\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return handler.getFlightInfo(session, descriptor);\n} catch (ArrowException e) {\n    if (e.getErrorCode().getCode() == ARROW_FLIGHT_INFO_ERROR.getCode()\n            && e.getCause() instanceof InterruptedException) {\n        // query was cancelled / worker shutting down: do not blind-retry,\n        // only retry if interruption was spurious and Thread.interrupted() is false\n    }\n    throw e;\n}","preventionTips":["Drain queries before worker restarts or deployments.","Check query cancellation is not being triggered spuriously by tight timeouts.","Restore the interrupt flag in wrapper code to keep cancellation semantics correct.","Keep getInfo calls short-lived so the interruption window is minimal."],"tags":["presto","arrow-flight","interrupted","rpc","cancellation"],"backgroundTag":"thread-interrupted-during-rpc","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}