apache/druid · critical · RE

Empty bitmapFullnessFactorizationStops:

Error message

Empty bitmapFullnessFactorizationStops: 

What it means

BitmapOffset parses the system property bitmapFullnessFactorizationStops in its static initializer. If the property is set to a value that, after splitting on commas, yields an empty array (or the property is set to an empty string such that the check triggers), it throws RequestTimeoutException-style RE 'Empty bitmapFullnessFactorizationStops: ' with the offending string. This static validation runs once per JVM when the class loads.

Source

Thrown at processing/src/main/java/org/apache/druid/segment/BitmapOffset.java:56

 */
public class BitmapOffset extends Offset
{
  private static final int INVALID_VALUE = -1;

  /**
   * Currently the default stops are not consciously optimized for the goals described in {@link #factorizeFullness}.
   * They are chosen intuitively. There was no experimentation with different bitmapFullnessFactorizationStops.
   * Experimentation and performance feedback with a different set of stops is welcome.
   */
  private static final String DEFAULT_FULLNESS_FACTORIZATION_STOPS = "0.01,0.1,0.3,0.5,0.7,0.9,0.99";
  private static final double[] BITMAP_FULLNESS_FACTORIZATION_STOPS;
  private static final String[] FACTORIZED_FULLNESS;

  static {
    String stopString = System.getProperty("bitmapFullnessFactorizationStops", DEFAULT_FULLNESS_FACTORIZATION_STOPS);
    String[] stopsArray = stopString.split(",");
    if (stopsArray.length == 0) {
      throw new RE("Empty bitmapFullnessFactorizationStops: " + stopString);
    }
    if (new HashSet<>(Arrays.asList(stopsArray)).size() != stopsArray.length) {
      throw new RE("Non unique bitmapFullnessFactorizationStops: " + stopString);
    }

    BITMAP_FULLNESS_FACTORIZATION_STOPS = new double[stopsArray.length];
    for (int i = 0; i < stopsArray.length; i++) {
      String stop = stopsArray[i];
      BITMAP_FULLNESS_FACTORIZATION_STOPS[i] = Double.parseDouble(stop);

    }
    Arrays.sort(BITMAP_FULLNESS_FACTORIZATION_STOPS);

    double firstStop = BITMAP_FULLNESS_FACTORIZATION_STOPS[0];
    if (Double.isNaN(firstStop) || firstStop <= 0.0) {
      throw new RE("First bitmapFullnessFactorizationStop[%d] should be > 0", firstStop);
    }
    double lastStop = BITMAP_FULLNESS_FACTORIZATION_STOPS[stopsArray.length - 1];

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Remove the -DbitmapFullnessFactorizationStops flag entirely to use DEFAULT_FULLNESS_FACTORIZATION_STOPS.
  2. Set the property to a comma-separated list of doubles strictly between 0 and 1, e.g. -DbitmapFullnessFactorizationStops=0.1,0.5,0.9.
  3. Fix the templating/config script so the variable is populated before the JVM starts.
  4. Restart the process after correcting jvm.config; this error is fatal at class-load.

Example fix

// before (jvm.config)
-DbitmapFullnessFactorizationStops=
// after
-DbitmapFullnessFactorizationStops=0.1,0.5,0.9
Defensive patterns

Strategy: validation

Validate before calling

String v = System.getProperty("bitmapFullnessFactorizationStops", "");
if (v != null && v.trim().isEmpty()) {
  throw new IllegalStateException("bitmapFullnessFactorizationStops must not be empty");
}

Try / catch

try {
  Class.forName("org.apache.druid.segment.BitmapOffset");
} catch (Throwable t) {
  throw new IllegalStateException("bad bitmapFullnessFactorizationStops: " + t.getMessage(), t);
}

Prevention

When it happens

Trigger: Starting a Druid process with -DbitmapFullnessFactorizationStops='' (or a value that splits to zero entries); note split(",") on a non-empty string always yields ≥1 element, so practically only an explicitly empty-string property triggers this on class load.

Common situations: Ops overrides in jvm.config that accidentally leave the property empty; templated configs where a variable meant to hold the stop list is unset, producing '-DbitmapFullnessFactorizationStops='; copy-paste of tuning knobs without values.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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