{"record":{"id":"3866511b82390291","repo":"apache/iceberg","slug":"failed-to-load-iceberg-table-from-table-loader-386651","errorCode":null,"errorMessage":"Failed to load iceberg table from table loader: ${tableLoader}","messagePattern":"Failed to load iceberg table from table loader: (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"critical","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/IcebergSink.java","lineNumber":919,"sourceCode":"  }\n\n  private static String defaultSuffix(String uidSuffix, String defaultSuffix) {\n    if (uidSuffix == null || uidSuffix.isEmpty()) {\n      return defaultSuffix;\n    }\n    return uidSuffix;\n  }\n\n  private static SerializableTable checkAndGetTable(TableLoader tableLoader, Table table) {\n    if (table == null) {\n      if (!tableLoader.isOpen()) {\n        tableLoader.open();\n      }\n\n      try (TableLoader loader = tableLoader) {\n        return (SerializableTable) SerializableTable.copyOf(loader.loadTable());\n      } catch (IOException e) {\n        throw new UncheckedIOException(\n            \"Failed to load iceberg table from table loader: \" + tableLoader, e);\n      }\n    }\n\n    return (SerializableTable) SerializableTable.copyOf(table);\n  }\n\n  /**\n   * Clean up after removing {@link Builder#tableSchema}\n   *\n   * @deprecated since 1.10.0, will be removed in 2.0.0. Use {@link #toFlinkRowType(Schema,\n   *     ResolvedSchema)} instead.\n   */\n  @Deprecated\n  private static RowType toFlinkRowType(Schema schema, TableSchema requestedSchema) {\n    if (requestedSchema != null) {\n      // Convert the flink schema to iceberg schema firstly, then reassign ids to match the existing\n      // iceberg schema.","sourceCodeStart":901,"sourceCodeEnd":937,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/IcebergSink.java#L901-L937","documentation":"IcebergSink's checkAndGetTable wraps any IOException from loader.loadTable() in an UncheckedIOException 'Failed to load iceberg table from table loader' when the Table argument is null and the table must be loaded from the TableLoader. It signals the Iceberg table could not be read from the catalog/filesystem at sink construction time; the cause holds the actual error.","triggerScenarios":"Constructing IcebergSink (or FlinkSink.invoke via the write builder) without passing a Table and with a TableLoader that fails to loadTable(): nonexistent table, catalog auth failure, unreachable warehouse, corrupt metadata JSON.","commonSituations":"Hive catalog kerberos/token expiry, wrong warehouse path in catalog config, S3 credentials absent on the job manager, table deleted between job planning and submission, or a TableLoader pointing at a location string instead of a registered catalog table.","solutions":["Eagerly call loader.open(); loader.loadTable() in your job setup to surface the root cause before submission","Verify catalog configuration (type/uri/warehouse) and that the identifier resolves (list tables in the catalog)","Check filesystem credentials (S3/HDFS/GCS) are present in the Flink configuration on JM and TMs","If the table was dropped/recreated, point the loader at the correct identifier or resubmit without stale state"],"exampleFix":"// before\nIcebergSink.forRowData(input)\n    .tableLoader(TableLoader.fromCatalog(catalogLoader, TableIdentifier.of(\"db\",\"missing\")))\n    .append();\n// after\nTableIdentifier id = TableIdentifier.of(\"db\", \"table\");\nCatalogLoader cl = CatalogLoader.hive(\"hive\", conf, hiveConf);\nTable t = cl.loadCatalog().loadTable(id); // fail fast with clear cause\nIcebergSink.forRowData(input)\n    .tableLoader(TableLoader.fromCatalog(cl, id))\n    .table(t) // or rely on validated loader\n    .append();","handlingStrategy":"validation","validationCode":"TableLoader loader = ...;\nloader.open();\nTable t = loader.loadTable(); // fail fast before job submission\nLOG.info(\"sink table {} spec {}\", t.name(), t.spec());","typeGuard":"boolean tableLoadable(TableLoader loader) {\n  try (TableLoader l = loader) {\n    if (!l.isOpen()) l.open();\n    return l.loadTable() != null;\n  } catch (Exception e) {\n    LOG.error(\"table load failed: {}\", e.toString());\n    return false;\n  }\n}","tryCatchPattern":"try {\n  sinkBuilder.append();\n} catch (UncheckedIOException e) {\n  LOG.error(\"table load failed, cause: {}\", e.getCause(), e);\n  throw new IllegalStateException(\"verify catalog config/credentials and table existence\", e);\n}","preventionTips":["Prefer catalog-based TableLoader (fromCatalog) over location-based loaders","Validate credentials for the storage backend on JM and TMs before launching","Check table existence/permissions with an independent catalog client","When passing an explicit Table to IcebergSink, loaders are bypassed — prefer that in tests"],"tags":["flink","table-loader","io","iceberg"],"backgroundTag":"file-read-failed","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"}