AdguardTeam/AdGuardHome · error

%s: parsing interval: %s

Error message

%s: parsing interval: %s

What it means

Returned by the stats HTTP handler when the 'recent' query parameter of GET /control/stats cannot be parsed as a base-10 64-bit integer. The raw strconv error is wrapped with the query key name for context.

Source

Thrown at internal/stats/http.go:108

		const msg = "Couldn't get statistics data"
		aghhttp.ErrorAndLog(ctx, l, r, w, http.StatusInternalServerError, msg)

		return
	}

	aghhttp.WriteJSONResponseOK(ctx, l, w, r, resp)
}

// parseRecent parses and validates the value of the recent URL parameter.  If
// the parameter is empty, the original limit is returned.
func parseRecent(recent string, limit time.Duration) (parsedLimit time.Duration, err error) {
	if recent == "" {
		return limit, nil
	}

	recentMs, err := strconv.ParseInt(recent, 10, 64)
	if err != nil {
		return 0, fmt.Errorf("%s: parsing interval: %s", queryKeyRecent, err)
	}

	err = validate.InRange(queryKeyRecent, recentMs, millisecondsInHour, limit.Milliseconds())
	if err != nil {
		// Don't wrap the error since it's already informative enough as is.
		return 0, err
	}

	if recentMs%millisecondsInHour != 0 {
		return 0, fmt.Errorf("%s: must be a multiple of 1 hour", queryKeyRecent)
	}

	return time.Duration(recentMs) * time.Millisecond, nil
}

// configResp is the response to the GET /control/stats_info.
type configResp struct {
	IntervalDays uint32 `json:"interval"`

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Send recent as an integer number of milliseconds, e.g. recent=7200000
  2. Omit the parameter entirely if you want the default limit
  3. Check the client's URL-encoding/serialization of durations

Example fix

// before
GET /control/stats?recent=2h
// after
GET /control.stats?recent=7200000
Defensive patterns

Strategy: validation

Validate before calling

ms, err := strconv.ParseInt(recent, 10, 64)
if err != nil { return fmt.Errorf("recent must be integer milliseconds") }

Try / catch

resp, err := http.Get(url + "?recent=" + strconv.FormatInt(ms, 10))
if err != nil || resp.StatusCode != 200 { /* inspect body for parsing error */ }

Prevention

When it happens

Trigger: Calling /control/stats (handleStats -> parseRecent) with recent=<non-numeric>, e.g. recent=1h, recent=true, or an empty-ish/garbage value (empty string is allowed and returns the limit).

Common situations: Passing a human-readable duration ('2h') instead of milliseconds; truncated URLs; client code building the query string incorrectly.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/ffb3e2009627cff4. Report an issue: GitHub.