thanos-io/thanos · error · api.ApiError

negative ' ' is not accepted. Try a positive integer

Error message

negative '%s' is not accepted. Try a positive integer

What it means

After successfully parsing max_source_resolution, parseDownsamplingParamMillis rejects negative durations with a dedicated ErrorBadData message "negative 'max_source_resolution' is not accepted. Try a positive integer". A negative resolution is meaningless for downsampling, so it is explicitly refused.

Solutions

  1. Clamp the value to a positive duration (or zero/auto) in the client before sending
  2. Fix the sign of the computed expression producing the negative value
  3. Add client-side validation: reject values starting with '-' or parse and check < 0
  4. Use 'auto' instead of a computed value when unsure

Example fix

// before
res="-$interval"  # -5m
// after
res="$interval"   # 5m; or Math.max(0, parsed) in tooling
Defensive patterns

Strategy: validation

Validate before calling

function validatePositiveDuration(v) {
  if (typeof v === 'string' && (v === 'auto' || !v.startsWith('-'))) return v;
  const ms = parsePromDurationToMs(v);
  if (ms < 0) throw new Error('max_source_resolution must be positive');
  return v;
}

Type guard

null

Try / catch

try {
  const res = await fetch(url);
  const j = await res.json();
  if (j.status === 'error' && /negative.*max_source_resolution/.test(j.error)) throw new Error(j.error);
} catch (e) {
  if (/negative.*max_source_resolution/.test(e.message)) { /* clamp to 0 or 'auto' and retry */ }
  throw e;
}

Prevention

When it happens

Trigger: Passing max_source_resolution=-5m, -1h, or any negative duration on query/query_range or explain endpoints, typically from templated dashboards or arithmetic in scripts producing negative values.

Common situations: Grafana variables computed from interval math going negative; shell scripts doing $(($a - $b)) with reversed operands; copying a step value that was negated.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/0bbf42496e4a84b3. Report an issue: GitHub.

Appendix: source

Thrown at pkg/api/query/v1.go:383

}

func (qapi *QueryAPI) parseDownsamplingParamMillis(r *http.Request, defaultVal time.Duration) (maxResolutionMillis int64, _ *api.ApiError) {
	maxSourceResolution := 0 * time.Second

	val := r.FormValue(MaxSourceResolutionParam)
	if qapi.enableAutodownsampling || (val == "auto") {
		maxSourceResolution = defaultVal
	}
	if val != "" && val != "auto" {
		var err error
		maxSourceResolution, err = parseDuration(val)
		if err != nil {
			return 0, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Wrapf(err, "'%s' parameter", MaxSourceResolutionParam)}
		}
	}

	if maxSourceResolution < 0 {
		return 0, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("negative '%s' is not accepted. Try a positive integer", MaxSourceResolutionParam)}
	}

	return int64(maxSourceResolution / time.Millisecond), nil
}

func (qapi *QueryAPI) parsePartialResponseParam(r *http.Request, defaultEnablePartialResponse bool) (enablePartialResponse bool, _ *api.ApiError) {
	// Overwrite the cli flag when provided as a query parameter.
	if val := r.FormValue(PartialResponseParam); val != "" {
		var err error
		defaultEnablePartialResponse, err = strconv.ParseBool(val)
		if err != nil {
			return false, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Wrapf(err, "'%s' parameter", PartialResponseParam)}
		}
	}
	return defaultEnablePartialResponse, nil
}

func (qapi *QueryAPI) parseStep(r *http.Request, defaultRangeQueryStep time.Duration, rangeSeconds int64) (time.Duration, *api.ApiError) {

View on GitHub (pinned to 35b8b99117)