thanos-io/thanos · error

http.Error(w, err.Error(), http.StatusInternalServerError)

Error message

http.Error(w, err.Error(), http.StatusInternalServerError)

What it means

The rule component's HTTP /-/reload endpoint forwards a reload request to the main run.Group via a channel and waits for the result. If the web handler reload returns an error, it is written verbatim to the HTTP response with status 500 via http.Error. This is the surface expression of any reload failure (bad rule files, query API issues).

Solutions

  1. Read the response body of the 500 — it contains the underlying reload error (e.g. YAML parse failure).
  2. Validate rule files with promtool check rules before deploying and reloading.
  3. Fix the offending rule file/glob and POST /-/reload again.
  4. Check component logs for the full error chain (retrieving rule files failed / reloading rules failed).

Example fix

// before
curl -XPOST http://thanos-rule:10902/-/reload   # returns 500: parsing YAML file ... failed
// after
promtool check rules /etc/thanos/rules/*.yaml && curl -XPOST http://thanos-rule:10902/-/reload
Defensive patterns

Strategy: try-catch

Validate before calling

promtool check rules /etc/thanos/rules/*.yaml || exit 1   # run before triggering reload

Try / catch

resp, err := http.Post(reloadURL, "", nil)
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode == http.StatusInternalServerError {
  log.Fatalf("reload failed: %s", body) // body holds the underlying rule error
}

Prevention

When it happens

Trigger: POSTing to http://<rule>/-/reload when reloadRules fails: a rule file matches a bad glob, a rule file fails parsing/validation, or ruleMgr.Update returns an error.

Common situations: CI/CD pushing a broken rules YAML then calling /-/reload; a renamed rules directory making a glob match nothing or an invalid pattern; SIGHUP-equivalent automation relying on reload endpoint.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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

Appendix: source

Thrown at cmd/thanos/rule.go:851

	{
		router := route.New()

		// RoutePrefix must always start with '/'.
		conf.web.routePrefix = "/" + strings.Trim(conf.web.routePrefix, "/")

		// Redirect from / to /webRoutePrefix.
		if conf.web.routePrefix != "/" {
			router.Get("/", func(w http.ResponseWriter, r *http.Request) {
				http.Redirect(w, r, conf.web.routePrefix, http.StatusFound)
			})
			router = router.WithPrefix(conf.web.routePrefix)
		}

		router.Post("/-/reload", func(w http.ResponseWriter, r *http.Request) {
			reloadMsg := make(chan error)
			reloadWebhandler <- reloadMsg
			if err := <-reloadMsg; err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
			}
		})

		ins := extpromhttp.NewInstrumentationMiddleware(reg, nil)

		// Configure Request Logging for HTTP calls.
		logMiddleware := logging.NewHTTPServerMiddleware(logger, httpLogOpts...)

		// TODO(bplotka in PR #513 review): pass all flags, not only the flags needed by prefix rewriting.
		ui.NewRuleUI(logger, reg, ruleMgr, conf.alertQueryURL.String(), conf.web.externalPrefix, conf.web.prefixHeaderName).Register(router, ins)

		api := v1.NewRuleAPI(logger, reg, thanosrules.NewGRPCClient(ruleMgr), ruleMgr, conf.web.disableCORS, flagsMap)
		api.Register(router.WithPrefix("/api/v1"), tracer, logger, ins, logMiddleware)

		srv := httpserver.New(logger, reg, comp, httpProbe,
			httpserver.WithListen(conf.http.bindAddress),
			httpserver.WithGracePeriod(time.Duration(conf.http.gracePeriod)),
			httpserver.WithTLSConfig(conf.http.tlsConfig),

View on GitHub (pinned to 35b8b99117)