apache/hadoop · error · IOException

Cannot fetch records for {clazz}

Error message

Cannot fetch records for {clazz}

What it means

StateStoreMySQLImpl executes a SELECT over the record table to fetch all records of a class; any SQLException — connection failure, missing table, schema drift, timeout, lock wait — is recorded as a state store metrics failure and wrapped as IOException('Cannot fetch records for <Class>') with the SQLException as cause. It signals the relational backend of the State Store failed to serve the query.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/store/driver/impl/StateStoreMySQLImpl.java:157

    StateStoreMetrics metrics = getMetrics();
    List<T> ret = new ArrayList<>();
    try (Connection connection = connectionFactory.getConnection();
        PreparedStatement statement = connection.prepareStatement(
            String.format("SELECT * FROM %s", tableName))) {
      try (ResultSet result = statement.executeQuery()) {
        while(result.next()) {
          String recordValue = result.getString("recordValue");
          T record = newRecord(recordValue, clazz, false);
          ret.add(record);
        }
      }
    } catch (SQLException e) {
      if (metrics != null) {
        metrics.addFailure(Time.monotonicNow() - start);
      }
      String msg = "Cannot fetch records for " + clazz.getSimpleName();
      LOG.error(msg, e);
      throw new IOException(msg, e);
    }

    if (metrics != null) {
      metrics.addRead(Time.monotonicNow() - start);
    }
    return new QueryResult<>(ret, getTime());
  }

  @Override
  public <T extends BaseRecord> StateStoreOperationResult putAll(
      List<T> records, boolean allowUpdate, boolean errorIfExists) throws IOException {
    if (records.isEmpty()) {
      return StateStoreOperationResult.getDefaultSuccessResult();
    }

    verifyDriverReady();
    StateStoreMetrics metrics = getMetrics();

View on GitHub (pinned to 2add963021)

Solutions

  1. Check the router log — LOG.error prints the SQLException with SQLState/error code identifying the exact failure.
  2. Provision the missing schema tables for the record class named in the message.
  3. Verify JDBC connectivity and credentials from the router host with the same URL.
  4. Tune the connection pool / timeouts if the cause is exhaustion or lock waits, then restart the router.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: schema must contain the record tables before router start
try (Connection c = dataSource.getConnection(); ResultSet rs = c.getMetaData()
        .getTables(null, null, "MembershipState", null)) {
  if (!rs.next()) throw new IllegalStateException("State store schema missing");
}

Try / catch

try {
  QueryResult<T> r = driver.fetchAll(clazz);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Cannot fetch records")
      && e.getCause() instanceof SQLException) {
    SQLException sql = (SQLException) e.getCause();
    if ("08*".startsWith(String.valueOf(sql.getSQLState())) // connection class
        || sql.getSQLState() == null) {
      retryWithBackoff(); // transient DB issue
    } else {
      throw e; // missing table / SQL error: fix schema
    }
  } else { throw e; }
}

Prevention

When it happens

Trigger: MySQL down or network-partitioned; the record table for the named class was never created (schema not provisioned); wrong JDBC URL/credentials; connection pool exhausted; lock wait timeout or query timeout under heavy router load; charset/collation mismatch producing SQL errors.

Common situations: First deployment where the MySQL State Store DDL was not applied; DB restart or failover while routers query it; wrong database name in the JDBC URL; pool sized below router concurrency.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/6dec817186e66c44. Report an issue: GitHub.