{"record":{"id":"3c69d3d512a4b048","repo":"apache/beam","slug":"table-s-row-s-mutation-failed-table-available-enabled-s-s","errorCode":null,"errorMessage":"Table %s row %s mutation failed. \nTable Available/Enabled: %s %s \nConnection Closed/Aborted/Locks: %s %s","messagePattern":"Table (.+?) row (.+?) mutation failed\\. \nTable Available/Enabled: (.+?) (.+?) \nConnection Closed/Aborted/Locks: (.+?) (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseIO.java","lineNumber":1020,"sourceCode":"          HBaseSharedConnection.close(configuration);\n        } catch (Exception e) {\n          failure = appendSuppressed(failure, e);\n        }\n        if (failure != null) {\n          rethrowCloseFailure(failure);\n        }\n      }\n\n      @ProcessElement\n      public void processElement(ProcessContext c) throws IOException {\n        RowMutations mutations = c.element().getValue();\n\n        try {\n          // Use Table instead of BufferedMutator to preserve mutation-ordering\n          table.mutateRow(mutations);\n          recordsWritten++;\n        } catch (IOException e) {\n          throw new RuntimeException(\n              String.join(\n                  \" \",\n                  \"Table\",\n                  tableId,\n                  \"row\",\n                  Bytes.toString(mutations.getRow()),\n                  \"mutation failed.\",\n                  \"\\nTable Available/Enabled:\",\n                  Boolean.toString(\n                      connection.getAdmin().isTableAvailable(TableName.valueOf(tableId))),\n                  Boolean.toString(\n                      connection.getAdmin().isTableEnabled(TableName.valueOf(tableId))),\n                  \"\\nConnection Closed/Aborted/Locks:\",\n                  Boolean.toString(connection.isClosed()),\n                  Boolean.toString(connection.isAborted())));\n        }\n      }\n","sourceCodeStart":1002,"sourceCodeEnd":1038,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseIO.java#L1002-L1038","documentation":"HBaseIO's write uses Table.mutateRow to preserve mutation ordering. If mutateRow throws an IOException, it is wrapped in a RuntimeException containing the table id, row key, and diagnostics about table availability, connection state, and locks so the failing row can be identified.","triggerScenarios":"Writing a batch of mutations to HBase via HBaseIO.write().to() when table.mutateRow(mutations) throws IOException — server unavailable, region moved, table disabled, connection closed, row lock conflict, or RPC timeout.","commonSituations":"HBase cluster unreachable from workers; table disabled or being split; RegionServer restart during write; DoNotRetryIOException from an oversized row/mutation; wrong table name.","solutions":["Read the detailed message: confirm the table exists and is enabled (via HBase shell 'is_enabled').","Check the connection configuration (quorum, znode, port) matches your cluster and is reachable from workers.","Retry failed rows — transient region moves/timeouts are common; Beam's sink may or may not retry depending on configuration.","Verify row/mutation size limits (e.g. hbase.client.keyvalue.maxsize) if the cause is DoNotRetryIOException."],"exampleFix":"// before\nHBaseIO.write().to(\"wrong_table\").withConfiguration(conf);\n// after\ntry (Connection c = ConnectionFactory.createConnection(conf);\n     Admin admin = c.getAdmin()) {\n  if (!admin.tableExists(TableName.valueOf(\"my_table\")) || !admin.isTableEnabled(TableName.valueOf(\"my_table\"))) {\n    throw new IllegalStateException(\"table missing or disabled\");\n  }\n}\nHBaseIO.write().to(\"my_table\").withConfiguration(conf);","handlingStrategy":"retry","validationCode":"try (Connection c = ConnectionFactory.createConnection(conf); Admin admin = c.getAdmin()) {\n  TableName tn = TableName.valueOf(tableId);\n  if (!admin.tableExists(tn)) throw new IllegalStateException(\"table missing: \" + tableId);\n  if (!admin.isTableEnabled(tn)) throw new IllegalStateException(\"table disabled: \" + tableId);\n}","typeGuard":null,"tryCatchPattern":"try {\n  table.mutateRow(mutations);\n} catch (IOException e) {\n  if (e instanceof RetriesExhaustedException || e instanceof SocketTimeoutException) {\n    // transient: backoff and retry once\n    sleepBackoff();\n    table.mutateRow(mutations);\n  } else {\n    throw new RuntimeException(\"permanent mutation failure for row \" + Bytes.toString(mutations.getRow()), e);\n  }\n}","preventionTips":["Validate the table exists and is enabled before the pipeline starts.","Confirm HBase quorum/zookeeper config is reachable from every worker node.","Keep rows/mutations under size limits to avoid DoNotRetryIOException.","Use unique row keys per element where possible to avoid lock contention.","Schedule pipelines away from cluster maintenance/split windows."],"tags":["hbase","write-failure","mutation","bigtable"],"backgroundTag":"database-write-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}