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
- 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.
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
- 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)
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
- Non unique bitmapFullnessFactorizationStops:
- First bitmapFullnessFactorizationStop[%d] should be > 0
- Last bitmapFullnessFactorizationStop[%d] should be < 1
- Only positive integers or zero can be added
- Cannot remove non Integer from integer BitSet
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/13209de4e56e8737.
Report an issue: GitHub.