{"record":{"id":"9d9ffb2d60d82ffd","repo":"apache/druid","slug":"unable-to-obtain-metadata-from-result-set","errorCode":null,"errorMessage":"Unable to obtain metadata from result set","messagePattern":"Unable to obtain metadata from result set","errorType":"exception","errorClass":"ResultSetException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/metadata/input/SqlEntity.java","lineNumber":139,"sourceCode":"    try (FileOutputStream fos = new FileOutputStream(tempFile);\n         final JsonGenerator jg = objectMapper.getFactory().createGenerator(fos)) {\n      final SerializerProvider serializers = objectMapper.getSerializerProviderInstance();\n\n      // Execute the sql query and lazily retrieve the results into the file in json format.\n      // foldCase is useful to handle differences in case sensitivity behavior across databases.\n      sqlInputSourceDatabaseConnector.retryWithHandle(\n          (handle) -> {\n            ResultIterator<Map<String, Object>> resultIterator = handle.createQuery(\n                sql\n            ).map(\n                (index, r, ctx) -> {\n                  Map<String, Object> resultRow = foldCase ? new CaseFoldedMap() : new HashMap<>();\n                  ResultSetMetaData resultMetadata;\n                  try {\n                    resultMetadata = r.getMetaData();\n                  }\n                  catch (SQLException e) {\n                    throw new ResultSetException(\"Unable to obtain metadata from result set\", e, ctx);\n                  }\n                  try {\n                    for (int i = 1; i <= resultMetadata.getColumnCount(); i++) {\n                      String key = resultMetadata.getColumnName(i);\n                      String alias = resultMetadata.getColumnLabel(i);\n                      Object value = r.getObject(i);\n                      resultRow.put(alias != null ? alias : key, value);\n                    }\n                  }\n                  catch (SQLException e) {\n                    throw new ResultSetException(\"Unable to access specific metadata from \" +\n                                                 \"result set metadata\", e, ctx);\n                  }\n                  return resultRow;\n                }\n            ).iterator();\n            jg.writeStartArray();\n            while (resultIterator.hasNext()) {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/metadata/input/SqlEntity.java#L121-L157","documentation":"When SqlEntity.fetch() streams ResultSet rows to JSON, it first obtains the JDBC ResultSetMetaData via r.getMetaData(). If the driver throws a SQLException at that point, it wraps it in a JdbcQueryException/ResultSetException with the message 'Unable to obtain metadata from result set'. This indicates the driver could not produce metadata for the executed statement (e.g., statement no longer valid, connection dropped).","triggerScenarios":"Executing a SQL query whose ResultSet metadata cannot be retrieved: closed/dead connection mid-fetch, driver error on getMetaData(), or statement execution that produced no valid metadata (some drivers throw for non-query statements or after cancellation).","commonSituations":"Network interruption between metadata broker and the SQL endpoint; query timeout/cancel racing the fetch; driver-specific bugs (e.g., old JDBC drivers) when retrieving metadata; using a connection after it was invalidated.","solutions":["Check broker connectivity and retry the query; the underlying SQLException is attached as the cause.","Verify the JDBC driver version is compatible with the SQL endpoint and upgrade it.","Increase query timeouts so the ResultSet is not invalidated mid-fetch.","Inspect the wrapped cause to identify the driver-level failure (connection reset, timeout, etc.)."],"exampleFix":"// before\nresultMetadata = r.getMetaData();\n// after\ntry (Statement stmt = conn.createStatement()) {\n  stmt.setQueryTimeout(QUERY_TIMEOUT_SECONDS); // keep result set valid during fetch\n  // execute and fetch metadata with retry on transient SQLException\n}","handlingStrategy":"try-catch","validationCode":"// verify connectivity before querying\ntry (Connection c = dataSource.getConnection()) {\n  if (!c.isValid(5)) throw new IllegalStateException(\"connection invalid\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  sqlEntity.fetch(tempDir, buffer);\n} catch (ResultSetException e) {\n  Throwable cause = e.getCause(); // SQLException: check connectivity/driver\n  // retry or surface a user-facing query error\n}","preventionTips":["Keep JDBC drivers up to date","Set adequate query/socket timeouts","Monitor broker-to-SQL-endpoint connectivity"],"tags":["jdbc","sql","metadata"],"backgroundTag":"database-query-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}