thanos-io/thanos · error

failed to parse the template

Error message

failed to parse the template: %w

What it means

validateTemplate in cmd/thanos/rule.go parses a user-supplied URL template with template.New("test").Parse to validate it at startup. If parsing fails it returns fmt.Errorf("failed to parse the template: %w", err). This is the startup-time validation counterpart of the runtime URL-template parse error, meant to fail fast on bad templates.

Solutions

  1. Read the wrapped template.ParseError in the message: it gives the line/column and reason for the syntax failure.
  2. Correct the template to valid Go text/template syntax with balanced {{ }} actions.
  3. Reference only the .Expr field in actions so validation's Execute step (Expression{Expr: "test_expr"}) also passes.
  4. Pre-validate the string with a quick `template.New("t").Parse(s)` snippet in a Go playground before deploying.

Example fix

// before
validateTemplate("/graph?g0.expr={{ .Expr ")
// after
validateTemplate("/graph?g0.expr={{ .Expr }}")
Defensive patterns

Strategy: validation

Validate before calling

func validateTemplate(tmplStr string) error {
    _, err := template.New("test").Parse(tmplStr)
    return err // nil means parseable
}

Type guard

null

Try / catch

if err := validateTemplate(tmplStr); err != nil {
    var pe *template.ParseError
    if errors.As(err, &pe) {
        log.Printf("template syntax error line %d col %d: %v", pe.Line, pe.Column, pe)
    }
}

Prevention

When it happens

Trigger: Calling validateTemplate(tmplStr) with a string that is not valid Go template syntax — unbalanced {{ }} delimiters, malformed actions, or unclosed comments — so Parse returns a parse error.

Common situations: Thanos rule starts with a bad --alert.query-template / URL template flag value; config management (Ansible/Helm) renders braces incorrectly; users mix Go template syntax with other templating dialects.

Understand the failure class

Related errors


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

Appendix: source

Thrown at cmd/thanos/rule.go:1143

	escapedExpression := url.QueryEscape(expr)

	escapedExpr := Expression{Expr: escapedExpression}
	t, err := texttemplate.New("url").Parse(tmpl)
	if err != nil {
		return "", errors.Wrap(err, "failed to parse template")
	}

	var buf bytes.Buffer
	if err := t.Execute(&buf, escapedExpr); err != nil {
		return "", errors.Wrap(err, "failed to execute template")
	}
	return buf.String(), nil
}

func validateTemplate(tmplStr string) error {
	tmpl, err := template.New("test").Parse(tmplStr)
	if err != nil {
		return fmt.Errorf("failed to parse the template: %w", err)
	}
	var buf bytes.Buffer
	err = tmpl.Execute(&buf, Expression{Expr: "test_expr"})
	if err != nil {
		return fmt.Errorf("failed to execute the template: %w", err)
	}
	return nil
}

// Filter out PromQL related warnings from warning response and keep store related warnings only.
func filterOutPromQLWarnings(warns []string, logger log.Logger, query string) []string {
	storeWarnings := make([]string, 0, len(warns))
	for _, warn := range warns {
		if extannotations.IsPromQLAnnotation(warn) {
			level.Warn(logger).Log("warning", warn, "query", query)
			continue
		}
		storeWarnings = append(storeWarnings, warn)

View on GitHub (pinned to 35b8b99117)