nats-io/nats-server · error
RTT threshold values %v should be in ascending order
Error message
RTT threshold values %v should be in ascending order
What it means
When validating a server/compression Options RTTThresholds list, each non-zero threshold must appear in ascending order — they map RTT ranges to compression levels. If a newly provided value is smaller than any previously accepted threshold, the configuration is invalid and server Options validation fails.
Source
Thrown at server/server.go:518
case "accept":
c.Mode = CompressionAccept
case "auto", "s2_auto":
var rtts []time.Duration
if len(c.RTTThresholds) == 0 {
rtts = defaultCompressionS2AutoRTTThresholds
} else {
for _, n := range c.RTTThresholds {
// Do not error on negative, but simply set to 0
if n < 0 {
n = 0
}
// Make sure they are properly ordered. However, it is possible
// to have a "0" anywhere in the list to indicate that this
// compression level should not be used.
if l := len(rtts); l > 0 && n != 0 {
for _, v := range rtts {
if n < v {
return fmt.Errorf("RTT threshold values %v should be in ascending order", c.RTTThresholds)
}
}
}
rtts = append(rtts, n)
}
if len(rtts) > 0 {
// Trim 0 that are at the end.
stop := -1
for i := len(rtts) - 1; i >= 0; i-- {
if rtts[i] != 0 {
stop = i
break
}
}
rtts = rtts[:stop+1]
}
if len(rtts) > 4 {
// There should be at most values for "uncompressed", "fast",View on GitHub (pinned to 3a66a489d2)
Solutions
- Sort RTTThresholds ascending before applying Options
- Keep 0 entries anywhere (they disable a level) but ensure all non-zero values increase monotonically
- Build the slice from a sorted structure, not a map
- Validate the config in CI before deploying
Example fix
// before
c.RTTThresholds = []int64{300, 100, 200}
// after
thresholds := []int64{300, 100, 200}
thresholds = append([]int64{0}, thresholds...) // placeholder
sort.Slice(thresholds, func(i, j int) bool { return thresholds[i] < thresholds[j] })
c.RTTThresholds = thresholds Defensive patterns
Strategy: validation
Validate before calling
// Go: validate RTTThresholds ordering before applying Options
func validRTTThresholds(t []int64) bool {
prev := int64(0)
for _, v := range t {
if v != 0 {
if prev != 0 && v < prev {
return false
}
prev = v
}
}
return true
} Prevention
- Sort threshold slices before assigning to Options
- Never build ordered config from Go map iteration
- Run server Options validation in CI config tests
When it happens
Trigger: Setting Options.RTTThresholds (compression mode thresholds) to something like [200, 100, 300] — a later non-zero value smaller than an earlier one.
Common situations: Hand-editing config files and reordering thresholds, programmatically building the slice from an unordered map (Go map iteration order is random), or merging configs from different sources.
Related errors
- compression mode %q should have no more than 4 RTT threshold
- failed to create mapping transform for stream import subject
- store operation not supported for URL Resolver
- delete must be enabled in server config
- Fetch timeout %v is too smal
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/61d7ebe03da31058.
Report an issue: GitHub.