{"record":{"id":"13209de4e56e8737","repo":"apache/druid","slug":"empty-bitmapfullnessfactorizationstops","errorCode":null,"errorMessage":"Empty bitmapFullnessFactorizationStops: ","messagePattern":"Empty bitmapFullnessFactorizationStops: ","errorType":"validation","errorClass":"RE","httpStatus":null,"severity":"critical","filePath":"processing/src/main/java/org/apache/druid/segment/BitmapOffset.java","lineNumber":56,"sourceCode":" */\npublic class BitmapOffset extends Offset\n{\n  private static final int INVALID_VALUE = -1;\n\n  /**\n   * Currently the default stops are not consciously optimized for the goals described in {@link #factorizeFullness}.\n   * They are chosen intuitively. There was no experimentation with different bitmapFullnessFactorizationStops.\n   * Experimentation and performance feedback with a different set of stops is welcome.\n   */\n  private static final String DEFAULT_FULLNESS_FACTORIZATION_STOPS = \"0.01,0.1,0.3,0.5,0.7,0.9,0.99\";\n  private static final double[] BITMAP_FULLNESS_FACTORIZATION_STOPS;\n  private static final String[] FACTORIZED_FULLNESS;\n\n  static {\n    String stopString = System.getProperty(\"bitmapFullnessFactorizationStops\", DEFAULT_FULLNESS_FACTORIZATION_STOPS);\n    String[] stopsArray = stopString.split(\",\");\n    if (stopsArray.length == 0) {\n      throw new RE(\"Empty bitmapFullnessFactorizationStops: \" + stopString);\n    }\n    if (new HashSet<>(Arrays.asList(stopsArray)).size() != stopsArray.length) {\n      throw new RE(\"Non unique bitmapFullnessFactorizationStops: \" + stopString);\n    }\n\n    BITMAP_FULLNESS_FACTORIZATION_STOPS = new double[stopsArray.length];\n    for (int i = 0; i < stopsArray.length; i++) {\n      String stop = stopsArray[i];\n      BITMAP_FULLNESS_FACTORIZATION_STOPS[i] = Double.parseDouble(stop);\n\n    }\n    Arrays.sort(BITMAP_FULLNESS_FACTORIZATION_STOPS);\n\n    double firstStop = BITMAP_FULLNESS_FACTORIZATION_STOPS[0];\n    if (Double.isNaN(firstStop) || firstStop <= 0.0) {\n      throw new RE(\"First bitmapFullnessFactorizationStop[%d] should be > 0\", firstStop);\n    }\n    double lastStop = BITMAP_FULLNESS_FACTORIZATION_STOPS[stopsArray.length - 1];","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/BitmapOffset.java#L38-L74","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove the -DbitmapFullnessFactorizationStops flag entirely to use DEFAULT_FULLNESS_FACTORIZATION_STOPS.","Set the property to a comma-separated list of doubles strictly between 0 and 1, e.g. -DbitmapFullnessFactorizationStops=0.1,0.5,0.9.","Fix the templating/config script so the variable is populated before the JVM starts.","Restart the process after correcting jvm.config; this error is fatal at class-load."],"exampleFix":"// before (jvm.config)\n-DbitmapFullnessFactorizationStops=\n// after\n-DbitmapFullnessFactorizationStops=0.1,0.5,0.9","handlingStrategy":"validation","validationCode":"String v = System.getProperty(\"bitmapFullnessFactorizationStops\", \"\");\nif (v != null && v.trim().isEmpty()) {\n  throw new IllegalStateException(\"bitmapFullnessFactorizationStops must not be empty\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  Class.forName(\"org.apache.druid.segment.BitmapOffset\");\n} catch (Throwable t) {\n  throw new IllegalStateException(\"bad bitmapFullnessFactorizationStops: \" + t.getMessage(), t);\n}","preventionTips":["Never set bitmapFullnessFactorizationStops to an empty string; omit the flag to use defaults","Validate jvm.config templates so variables cannot render as blank flags","Smoke-test JVM startup flags in CI before rollout","Keep comma-separated stop lists well-formed (doubles in (0,1), unique)"],"tags":["java","jvm-properties","static-init","segment","bitmap"],"backgroundTag":"invalid-config-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}