apache/druid · critical · ProvisionException

druid.segmentCache.locations must be set on historicals.

Error message

druid.segmentCache.locations must be set on historicals.

What it means

When building DataNodeService, if the segment cache is not configured and the node's ServerType is HISTORICAL, provisioning fails: historicals must have segment cache locations (druid.segmentCache.locations) to serve segments. Non-historical types only log a warning.

Source

Thrown at server/src/main/java/org/apache/druid/guice/StorageNodeModule.java:119

  @Provides
  @LazySingleton
  public DataNodeService getDataNodeService(
      @Nullable ServerTypeConfig serverTypeConfig,
      DruidServerConfig config,
      @Named(IS_SEGMENT_CACHE_CONFIGURED) Boolean isSegmentCacheConfigured
  )
  {
    if (serverTypeConfig == null) {
      throw new ProvisionException("Must override the binding for ServerTypeConfig if you want a DataNodeService.");
    }
    if (!isSegmentCacheConfigured) {
      log.info(
          "Segment cache not configured on ServerType [%s]. It will not be assignable for segment placement",
          serverTypeConfig.getServerType()
      );
      if (ServerType.HISTORICAL.equals(serverTypeConfig.getServerType())) {
        throw new ProvisionException("druid.segmentCache.locations must be set on historicals.");
      }
    }

    return new DataNodeService(
        config.getTier(),
        config.getMaxSize(),
        config.getStorageSize(),
        serverTypeConfig.getServerType(),
        config.getPriority(),
        isSegmentCacheConfigured
    );
  }

  @Provides
  @ManageLifecycle
  public StorageLoadingThreadPool getStorageLoadingThreadPool(SegmentLoaderConfig config)
  {
    return StorageLoadingThreadPool.createFromConfig(config);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Set druid.segmentCache.locations to one or more valid local directories
  2. Verify druid.segmentCache.locations is parsed (correct JSON list form: [{"path":"/var/druid/segment-cache","maxSize":...}])
  3. If the node is not meant to be a historical, correct the configured ServerType

Example fix

// before
druid.segmentCache.locations=   # unset
// after
druid.segmentCache.locations=[{"path":"/var/druid/segment-cache","maxSize":300000000000}]
Defensive patterns

Strategy: validation

Validate before calling

if (serverType == ServerType.HISTORICAL &&
    (segmentCacheConfig == null || segmentCacheConfig.getLocations() == null || segmentCacheConfig.getLocations().isEmpty())) {
  throw new IllegalArgumentException("historicals require druid.segmentCache.locations");
}

Try / catch

try {
  injector.getInstance(DataNodeService.class);
} catch (ProvisionException e) {
  if (e.getMessage().contains("druid.segmentCache.locations")) {
    log.error("Configure druid.segmentCache.locations for this historical");
  }
  throw e;
}

Prevention

When it happens

Trigger: Starting a historical with no druid.segmentCache.locations configured; isSegmentCacheConfigured is false while serverTypeConfig.getServerType() is HISTORICAL.

Common situations: Fresh historical deployments missing segment cache config; copying broker configs to historicals; cache locations pointing to invalid paths so cache is treated as unconfigured.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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