{"record":{"id":"e5b4fb2d32c46f1e","repo":"apache/iceberg","slug":"interrupted-in-call-to-listtables","errorCode":null,"errorMessage":"Interrupted in call to listTables","messagePattern":"Interrupted in call to listTables","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java","lineNumber":201,"sourceCode":"            listIcebergTablesByFilter(\n                namespace, BaseMetastoreTableOperations.ICEBERG_TABLE_TYPE_VALUE);\n      }\n\n      LOG.debug(\n          \"Listing of namespace: {} resulted in the following tables: {}\",\n          namespace,\n          tableIdentifiers);\n      return tableIdentifiers;\n\n    } catch (UnknownDBException e) {\n      throw new NoSuchNamespaceException(\"Namespace does not exist: %s\", namespace);\n\n    } catch (TException e) {\n      throw new RuntimeException(\"Failed to list all tables under namespace \" + namespace, e);\n\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new RuntimeException(\"Interrupted in call to listTables\", e);\n    }\n  }\n\n  @Override\n  public List<TableIdentifier> listViews(Namespace namespace) {\n    Preconditions.checkArgument(\n        isValidateNamespace(namespace), \"Missing database in namespace: %s\", namespace);\n\n    try {\n      String database = namespace.level(0);\n      List<String> viewNames =\n          clients.run(client -> client.getTables(database, \"*\", TableType.VIRTUAL_VIEW));\n\n      // Retrieving the Table objects from HMS in batches to avoid OOM\n      List<TableIdentifier> filteredTableIdentifiers = Lists.newArrayList();\n      Iterable<List<String>> viewNameSets = Iterables.partition(viewNames, 100);\n\n      for (List<String> viewNameSet : viewNameSets) {","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java#L183-L219","documentation":"HiveCatalog.listTables() throws RuntimeException(\"Interrupted in call to listTables\") when the thread waiting on the Hive metastore call (via the client pool) is interrupted. The handler restores the interrupt flag before throwing so callers can observe cancellation.","triggerScenarios":"The thread calling listTables() is interrupted while blocked waiting for an HMS client from CachedClientPool or for the metastore round-trip — e.g. task cancellation, query kill, or executor shutdown.","commonSituations":"Spark/Flink job cancelled while listing tables; executor shutdown with tasks in-flight; timeouts implemented via thread interruption; shutdown hooks interrupting workers.","solutions":["Avoid interrupting catalog calls during normal operation; cancel work at a coarser level","If intentional shutdown, catch RuntimeException and treat as cancellation","Ensure timeouts are configured at the metastore/client level instead of interrupting threads","Re-check the restored interrupt flag in calling code and exit promptly"],"exampleFix":"// before\nexecutor.shutdownNow(); // interrupts in-flight listTables\n// after\nexecutor.shutdown();\nexecutor.awaitTermination(60, TimeUnit.SECONDS); // let HMS calls finish","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { catalog.listTables(ns); } catch (RuntimeException e) { if (Thread.currentThread().isInterrupted()) { /* treat as cancellation, exit */ } }","preventionTips":["Use shutdown() + awaitTermination instead of shutdownNow() around catalog work","Configure client-level timeouts rather than interrupting threads","Check and honor the restored interrupt flag after catching"],"tags":["hive","interruption","concurrency"],"backgroundTag":"request-timeout","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}