{"record":{"id":"61d7ebe03da31058","repo":"nats-io/nats-server","slug":"rtt-threshold-values-v-should-be-in-ascending-ord","errorCode":null,"errorMessage":"RTT threshold values %v should be in ascending order","messagePattern":"RTT threshold values (.+?) should be in ascending order","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/server.go","lineNumber":518,"sourceCode":"\tcase \"accept\":\n\t\tc.Mode = CompressionAccept\n\tcase \"auto\", \"s2_auto\":\n\t\tvar rtts []time.Duration\n\t\tif len(c.RTTThresholds) == 0 {\n\t\t\trtts = defaultCompressionS2AutoRTTThresholds\n\t\t} else {\n\t\t\tfor _, n := range c.RTTThresholds {\n\t\t\t\t// Do not error on negative, but simply set to 0\n\t\t\t\tif n < 0 {\n\t\t\t\t\tn = 0\n\t\t\t\t}\n\t\t\t\t// Make sure they are properly ordered. However, it is possible\n\t\t\t\t// to have a \"0\" anywhere in the list to indicate that this\n\t\t\t\t// compression level should not be used.\n\t\t\t\tif l := len(rtts); l > 0 && n != 0 {\n\t\t\t\t\tfor _, v := range rtts {\n\t\t\t\t\t\tif n < v {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"RTT threshold values %v should be in ascending order\", c.RTTThresholds)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trtts = append(rtts, n)\n\t\t\t}\n\t\t\tif len(rtts) > 0 {\n\t\t\t\t// Trim 0 that are at the end.\n\t\t\t\tstop := -1\n\t\t\t\tfor i := len(rtts) - 1; i >= 0; i-- {\n\t\t\t\t\tif rtts[i] != 0 {\n\t\t\t\t\t\tstop = i\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trtts = rtts[:stop+1]\n\t\t\t}\n\t\t\tif len(rtts) > 4 {\n\t\t\t\t// There should be at most values for \"uncompressed\", \"fast\",","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/server.go#L500-L536","documentation":"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.","triggerScenarios":"Setting Options.RTTThresholds (compression mode thresholds) to something like [200, 100, 300] — a later non-zero value smaller than an earlier one.","commonSituations":"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.","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"],"exampleFix":"// before\nc.RTTThresholds = []int64{300, 100, 200}\n// after\nthresholds := []int64{300, 100, 200}\nthresholds = append([]int64{0}, thresholds...) // placeholder\nsort.Slice(thresholds, func(i, j int) bool { return thresholds[i] < thresholds[j] })\nc.RTTThresholds = thresholds","handlingStrategy":"validation","validationCode":"// Go: validate RTTThresholds ordering before applying Options\nfunc validRTTThresholds(t []int64) bool {\n    prev := int64(0)\n    for _, v := range t {\n        if v != 0 {\n            if prev != 0 && v < prev {\n                return false\n            }\n            prev = v\n        }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Sort threshold slices before assigning to Options","Never build ordered config from Go map iteration","Run server Options validation in CI config tests"],"tags":["nats-server","configuration","compression","options-validation"],"backgroundTag":"invalid-config-option","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}