apache/skywalking · error · IllegalArgumentException

Incompatible ranks size = [{value.getRanks().length}] for cu

Error message

Incompatible ranks size = [{value.getRanks().length}] for current PercentileFunction[{ranks.size()}]

What it means

After the first accept() locks the rank IntList for a sum_histogram_percentile metric in the current window, SumHistogramPercentileFunction requires every subsequent input to carry exactly the same NUMBER of ranks. This branch throws when value.getRanks().length differs from the locked ranks.size(), even if the values overlap.

Source

Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sum/SumHistogramPercentileFunction.java:113

    @Override
    public void accept(final MeterEntity entity, final PercentileArgument value) {
        if (summation.size() > 0) {
            if (!value.getBucketedValues().isCompatible(summation)) {
                throw new IllegalArgumentException(
                    "Incompatible BucketedValues [" + value + "] for current PercentileFunction[" + summation + "]");
            }
        }

        for (final int rank : value.getRanks()) {
            if (rank <= 0) {
                throw new IllegalArgumentException("Illegal rank value " + rank + ", must be positive");
            }
        }

        if (ranks.size() > 0) {
            if (ranks.size() != value.getRanks().length) {
                throw new IllegalArgumentException(
                    "Incompatible ranks size = [" + value.getRanks().length + "] for current PercentileFunction[" + ranks
                        .size() + "]");
            } else {
                for (final int rank : value.getRanks()) {
                    if (!ranks.include(rank)) {
                        throw new IllegalArgumentException(
                            "Rank " + rank + " doesn't exist in the previous ranks " + ranks);
                    }
                }
            }
        } else {
            for (final int rank : value.getRanks()) {
                ranks.add(rank);
            }
        }

        this.entityId = entity.id();

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Make the rank list identical (same values AND same count) across all producers of the metric
  2. Restart the whole OAP cluster after changing ranks so the next window re-locks the set
  3. Search all MAL rule files for the metric name and deduplicate/align the percentile expressions

Example fix

# before — inconsistent counts across rules
percentile(50, 75) -> sum_histogram_percentile
percentile(50, 75, 90) -> sum_histogram_percentile
# after
percentile(50, 75, 90) -> sum_histogram_percentile  (both rules)
Defensive patterns

Strategy: validation

Validate before calling

int[] incoming = argument.getRanks();
IntList locked = function.getRanks();
if (locked.size() > 0 && locked.size() != incoming.length) {
    log.warn("Rank count {} != locked {} for {}; drop", incoming.length, locked.size(), metricName);
    return;
}

Try / catch

try { function.accept(entity, argument); } catch (IllegalArgumentException e) { log.warn(...); /* drop sample, keep pipeline alive */ }

Prevention

When it happens

Trigger: First input in the window is percentile(50, 75, 90) (3 ranks) and a later input for the same metric is percentile(50, 75, 90, 99) (4 ranks) — size mismatch, 4 != 3.

Common situations: Adding/removing a rank in MAL config and rolling it out while the old config still reports; two MAL rules with the same metric name but different rank counts; multi-cluster OAP nodes with different config versions.

Related errors


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