{"record":{"id":"f11965c7d65d0dac","repo":"prestodb/presto","slug":"arrow-flight-metadata-error-f11965","errorCode":"ARROW_FLIGHT_METADATA_ERROR","errorMessage":"Error getting schema for flight: ","messagePattern":"Error getting schema for flight: ","errorType":"error_code","errorClass":"ArrowException","httpStatus":null,"severity":"warning","filePath":"presto-base-arrow-flight/src/main/java/com/facebook/plugin/arrow/BaseArrowFlightClientHandler.java","lineNumber":168,"sourceCode":"                    .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);\n        }\n    }\n\n    public Schema getSchema(ConnectorSession connectorSession, FlightDescriptor flightDescriptor)\n    {\n        try (FlightClient client = createFlightClient()) {\n            CallOption[] callOptions = this.getCallOptions(connectorSession);\n            return client.getSchema(flightDescriptor, callOptions).getSchema();\n        }\n        catch (InterruptedException e) {\n            throw new ArrowException(ARROW_FLIGHT_METADATA_ERROR, \"Error getting schema for flight: \" + e.getMessage(), e);\n        }\n    }\n\n    public abstract List<String> listSchemaNames(ConnectorSession session);\n\n    public abstract List<SchemaTableName> listTables(ConnectorSession session, Optional<String> schemaName);\n\n    protected abstract FlightDescriptor getFlightDescriptorForSchema(ConnectorSession session, String schemaName, String tableName);\n\n    protected abstract FlightDescriptor getFlightDescriptorForTableScan(ConnectorSession session, ArrowTableLayoutHandle tableLayoutHandle);\n\n    public Schema getSchemaForTable(ConnectorSession connectorSession, String schemaName, String tableName)\n    {\n        FlightDescriptor flightDescriptor = getFlightDescriptorForSchema(connectorSession, schemaName, tableName);\n        return getSchema(connectorSession, flightDescriptor);\n    }\n\n    public FlightInfo getFlightInfoForTableScan(ConnectorSession session, ArrowTableLayoutHandle tableLayoutHandle)","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-base-arrow-flight/src/main/java/com/facebook/plugin/arrow/BaseArrowFlightClientHandler.java#L150-L186","documentation":"getSchema performs FlightClient.getSchema(descriptor, callOptions) to retrieve an Arrow schema for a descriptor. An InterruptedException during the RPC is wrapped as ArrowException(ARROW_FLIGHT_METADATA_ERROR) with 'Error getting schema for flight: <msg>'. As with getFlightInfo, the interrupt flag is not restored before throwing.","triggerScenarios":"Calling getSchema (via getSchemaForTable, used by getColumnsList/listTableColumns) while the thread is interrupted — query cancellation, worker shutdown, or executor teardown during the schema RPC.","commonSituations":"SHOW COLUMNS / metadata resolution cancelled mid-query; Presto worker being decommissioned; system-level thread interrupts from overloaded schedulers.","solutions":["Rerun the metadata operation if interruption was from an intentional cancel.","Drain workers before restarts/deployments to avoid mid-RPC interrupts.","Check for overly aggressive cancellation/timeout settings in the deployment.","Restore the interrupt flag in custom subclasses to preserve cancellation semantics.","Ensure the Flight RPC completes quickly (server responsiveness) so the interruption window is small."],"exampleFix":"// before\ncatch (InterruptedException e) {\n    throw new ArrowException(ARROW_FLIGHT_METADATA_ERROR, \"Error getting schema for flight: \" + e.getMessage(), e);\n}\n// after\ncatch (InterruptedException e) {\n    Thread.currentThread().interrupt();\n    throw new ArrowException(ARROW_FLIGHT_METADATA_ERROR, \"Error getting schema for flight: \" + 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 getSchema\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return handler.getSchema(session, descriptor);\n} catch (ArrowException e) {\n    if (e.getErrorCode().getCode() == ARROW_FLIGHT_METADATA_ERROR.getCode()\n            && e.getCause() instanceof InterruptedException) {\n        // only retry if interruption was spurious; otherwise honor cancellation\n    }\n    throw e;\n}","preventionTips":["Avoid blocking metadata resolution behind long-running operations that can be interrupted.","Drain workers before shutdown; avoid killing threads mid-RPC.","Cache schemas to reduce RPC frequency and interruption exposure.","Restore the interrupt flag when wrapping InterruptedException in custom handlers."],"tags":["presto","arrow-flight","interrupted","schema","metadata"],"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"}