apache/druid · error · IllegalStateException

A realtime appenderator was already created for this peon's…

Error message

A realtime appenderator was already created for this peon's task.

What it means

PeonAppenderatorsManager manages at most one appenderator per peon (task worker process). createRealtimeAppenderatorForTask throws this IllegalStateException if a realtime appenderator already exists, because the manager only supports a single realtime appenderator for the lifetime of the peon.

Solutions

  1. Ensure createRealtimeAppenderatorForTask is called at most once per peon; guard with an initialized flag in task code
  2. Call the manager's shutdown/cleanup path before attempting to recreate the appenderator
  3. Check task logs for an earlier creation call and fix duplicate initialization in task lifecycle code

Example fix

// before
appenderatorManager.createRealtimeAppenderatorForTask(...) // called on both init and retry
// after
if (!initialized) {
  appenderator = appenderatorManager.createRealtimeAppenderatorForTask(...);
  initialized = true;
}
Defensive patterns

Strategy: validation

Validate before calling

if (peonManager.realtimeAppenderatorExists()) throw new IllegalStateException("appenderator already created");

Type guard

boolean canCreateRealtime = manager != null && !manager.hasRealtimeAppenderator();

Try / catch

try { manager.createRealtimeAppenderatorForTask(...); } catch (ISE e) { log.warn("already created; reusing existing appenderator"); }

Prevention

When it happens

Trigger: Calling createRealtimeAppenderatorForTask twice within the same peon process, e.g. task restart logic re-invoking appenderator creation without first calling shutdown, or custom task code re-entering initialization after a failure.

Common situations: Custom indexing task implementations that retry ingestion setup; frameworks re-invoking task initialization after transient failures; double registration of the same task in an embedded peon.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at server/src/main/java/org/apache/druid/segment/realtime/appenderator/PeonAppenderatorsManager.java:93

      IndexIO indexIO,
      IndexMerger indexMerger,
      QueryRunnerFactoryConglomerate conglomerate,
      DataSegmentAnnouncer segmentAnnouncer,
      ServiceEmitter emitter,
      QueryProcessingPool queryProcessingPool,
      JoinableFactory joinableFactory,
      Cache cache,
      CacheConfig cacheConfig,
      CachePopulatorStats cachePopulatorStats,
      PolicyEnforcer policyEnforcer,
      RowIngestionMeters rowIngestionMeters,
      ParseExceptionHandler parseExceptionHandler,
      CentralizedDatasourceSchemaConfig centralizedDatasourceSchemaConfig,
      TaskIntervalUnlocker taskIntervalUnlocker
  )
  {
    if (realtimeAppenderator != null) {
      throw new ISE("A realtime appenderator was already created for this peon's task.");
    } else if (batchAppenderator != null) {
      throw new ISE("A batch appenderator was already created for this peon's task.");
    } else {
      realtimeAppenderator = Appenderators.createRealtime(
          segmentLoaderConfig,
          taskId,
          schema,
          config,
          metrics,
          dataSegmentPusher,
          jsonMapper,
          indexIO,
          indexMerger,
          conglomerate,
          segmentAnnouncer,
          emitter,
          queryProcessingPool,
          cache,

View on GitHub (pinned to 9b90983fd2)