apache/skywalking · error · IllegalArgumentException
Rank {rank} doesn't exist in the previous ranks {ranks}
Error message
Rank {rank} doesn't exist in the previous ranks {ranks} What it means
Once the rank set of a sum_histogram_percentile metric is locked in the current time window, SumHistogramPercentileFunction checks each incoming rank with ranks.include(rank). This branch fires when the count matches but a specific rank value is not in the locked set — e.g. locked [50,75,90] receives [50,75,95].
Source
Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/meter/function/sum/SumHistogramPercentileFunction.java:119
"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();
String template = "%s";
if (CollectionUtils.isNotEmpty(value.getBucketedValues().getLabels())) {
template = value.getBucketedValues().getLabels() + ":%s";
}
final long[] values = value.getBucketedValues().getValues();
for (int i = 0; i < values.length; i++) {View on GitHub (pinned to 102af09b4a)
Solutions
- Align all rank values exactly across every producer of the metric
- Restart all OAP nodes together after the config change so a fresh window locks the new ranks
- Treat the percentile rank list as part of the metric contract: change it only with a coordinated rollout or a new metric name
Example fix
# before — first window input locks {50,75,90}, later input sends {50,75,95}
# after — all inputs use {50,75,90,99}
percentile(50, 75, 90, 99) -> sum_histogram_percentile Defensive patterns
Strategy: validation
Validate before calling
IntList locked = function.getRanks();
int[] incoming = argument.getRanks();
if (locked.size() > 0 && Arrays.stream(incoming).anyMatch(r -> !locked.include(r))) {
log.warn("Rank {} not in locked set {}; dropping", Arrays.toString(incoming), locked);
return;
} Try / catch
Catch IllegalArgumentException around accept(), log both rank sets, drop the sample; alert if mismatches persist across windows (indicates config drift, not a transient).
Prevention
- Version your meter configs and make rank lists part of the versioned contract
- During rolling upgrades, drain/finish the current window before activating new rank configs
- Monitor OAP logs for this message as a config-drift signal
When it happens
Trigger: A later input in the same window passes a rank value that was not in the first-accepted rank list, while the total count happens to match.
Common situations: Changing one percentile value (90 -> 95) in MAL config during a rolling upgrade; two agents with different firmware versions reporting the same metric name.
Related errors
- Rank {rank} doesn't exist in the previous ranks {ranks}
- Incompatible ranks size = [{value.getRanks().length}] for cu
- Incompatible BucketedValues [{value}] for current Percentile
- Illegal rank value {rank}, must be positive
- Illegal rank value {rank}, must be positive
AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14).
Data as JSON: /api/errors/263063cd73a58ad9.
Report an issue: GitHub.