apache/druid · error · DruidException

Encountered metadata exception for task

Error message

Encountered metadata exception for task [%s]

What it means

An unexpected Throwable occurred while inserting a task/lock entry (and its status payload) into the metadata store, so SQLMetadataStorageActionHandler wraps it in a DruidException with 'Encountered metadata exception for task [%s]'. The underlying SQL or serialization failure is wrapped and classified (transient vs not) for retry decisions.

Solutions

  1. Inspect the wrapped cause in the DruidException/logs to find the root SQL error and fix it (connectivity, credentials, schema).
  2. If transient (connection loss), retry the task submission/action after the DB recovers — transient causes are retried automatically where supported.
  3. Avoid resubmitting tasks with an existing id; check task status first or use a new id to prevent duplicate-key failures.

Example fix

// before
overlordClient.submitTask(sameIdSpec); // duplicate id -> metadata exception
// after
if (!taskClient.getStatus(sameId).isPresent()) {
  overlordClient.submitTask(sameIdSpec);
}
Defensive patterns

Strategy: retry

Try / catch

try {
  overlord.submitTask(spec);
} catch (DruidException e) {
  if (String.valueOf(e).contains("Encountered metadata exception for task")) {
    // inspect wrapped cause; retry with backoff only if transient (connection loss)
  }
}

Prevention

When it happens

Trigger: insert → insertEntryWithHandle → statement execute failing: DB connection loss, constraint violation (duplicate entry id), table missing/locked, or serialization of the status payload failing inside the withHandle callback.

Common situations: Metadata DB outage or failover mid-task; duplicate task id resubmission hitting a unique key; misconfigured metadata storage credentials; long transaction timeouts under load.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/c05b8ac86162a959. Report an issue: GitHub.

Appendix: source

Thrown at indexing-service/src/main/java/org/apache/druid/metadata/SQLMetadataStorageActionHandler.java:191

      final String sql = StringUtils.format(
          "INSERT INTO %s (id, created_date, datasource, payload, type, group_id, active, status_payload) "
          + "VALUES (:id, :created_date, :datasource, :payload, :type, :group_id, :active, :status_payload)",
          getEntryTable()
      );
      handle.createStatement(sql)
            .bind("id", entryId)
            .bind("created_date", timestamp.toString())
            .bind("datasource", dataSource)
            .bind("payload", jsonMapper.writeValueAsBytes(entry))
            .bind("type", type)
            .bind("group_id", groupId)
            .bind("active", active)
            .bind("status_payload", jsonMapper.writeValueAsBytes(status))
            .execute();
      return null;
    }
    catch (Throwable t) {
      throw wrapInDruidException(entryId, t);
    }
  }

  private boolean isTransientDruidException(Throwable t)
  {
    if (t instanceof CallbackFailedException) {
      return isTransientDruidException(t.getCause());
    } else if (t instanceof DruidException) {
      return Boolean.parseBoolean(((DruidException) t).getContextValue(CONTEXT_KEY_IS_TRANSIENT));
    } else {
      return getConnector().isTransientException(t);
    }
  }

  @Override
  public boolean setStatus(final String entryId, final boolean active, final TaskStatus status)
  {
    return connector.retryWithHandle(

View on GitHub (pinned to 9b90983fd2)