apache/skywalking · error · IllegalArgumentException

buckets and values can't be null.

Error message

buckets and values can't be null.

What it means

BucketedValues is the value object histogram meter functions accept; its constructor requires a non-null, non-empty buckets array and a non-null, non-empty values array. Violating any of the four conditions (either array null or zero-length) throws this IllegalArgumentException before any aggregation happens, protecting downstream index arithmetic that assumes buckets.length > 0.

Solutions

  1. Skip emitting the histogram metric for this cycle when buckets or values would be empty instead of constructing BucketedValues
  2. Fix the producer so it always sends a well-formed bucket set (bucket boundaries plus one value per bucket)
  3. Validate telemetry at the receiving boundary and reject/log malformed empty histograms before they reach accept()

Example fix

// before
long[] buckets = fetchBuckets(); // may be empty
new BucketedValues(buckets, values);

// after
long[] buckets = fetchBuckets();
if (buckets != null && buckets.length > 0 && values != null && values.length == buckets.length) {
    new BucketedValues(buckets, values);
} else {
    log.debug("Skip empty histogram for {}", metricName);
}
Defensive patterns

Strategy: validation

Validate before calling

if (buckets == null || values == null || buckets.length == 0 || values.length == 0) {
    log.debug("Skipping empty histogram for {}", metricName);
} else {
    BucketedValues bv = new BucketedValues(buckets, values);
    histogram.accept(entity, bv);
}

Type guard

boolean isWellFormedHistogram(long[] buckets, long[] values) {
    return buckets != null && values != null
        && buckets.length > 0 && values.length == buckets.length;
}

Prevention

When it happens

Trigger: A MAL rule or agent SDK builds BucketedValues from empty or null telemetry — e.g. a bucketed expression produced no points this cycle, or upstream code passes uninitialized arrays; a custom meter sender serializes an empty histogram.

Common situations: Meter/OTel receivers forwarding empty histogram batches; agent plugins computing buckets conditionally and passing null when the condition fails; test fixtures with empty arrays.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/ef6d8d9a83a4eebf. Report an issue: GitHub.

Appendix: source

Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/BucketedValues.java:59

     * The element in the buckets represent the minimal value of this bucket, the max is defined by the next element.
     * Such as 0, 10, 50, 100 means buckets are [0, 10), [10, 50), [50, 100), [100, infinite+).
     *
     * The {@link Long#MIN_VALUE} could be the first bucket element to indicate there is no minimal value.
     */
    private long[] buckets;
    /**
     * {@link #buckets} and {@link #values} arrays should have the same length. The element in the values, represents
     * the amount in the same index bucket.
     */
    private long[] values;

    /**
     * @param buckets Read {@link #buckets}
     * @param values  Read {@link #values}
     */
    public BucketedValues(final long[] buckets, final long[] values) {
        if (buckets == null || values == null || buckets.length == 0 || values.length == 0) {
            throw new IllegalArgumentException("buckets and values can't be null.");
        }
        if (buckets.length != values.length) {
            throw new IllegalArgumentException("The length of buckets and values should be same.");
        }
        this.buckets = buckets;
        this.values = values;
    }

    /**
     * @return true if the bucket is same.
     */
    public boolean isCompatible(DataTable dataset) {
        final List<String> sortedKeys = dataset.sortedKeys(new HeatMap.KeyComparator(true));
        long[] existedBuckets = new long[sortedKeys.size()];
        for (int i = 0; i < sortedKeys.size(); i++) {
            String key = sortedKeys.get(i);
            if (key.equals(Bucket.INFINITE_NEGATIVE)) {
                existedBuckets[i] = Long.MIN_VALUE;

View on GitHub (pinned to 102af09b4a)