thanos-io/thanos · error

rule: alerting rule unmarshal

Error message

rule: alerting rule unmarshal: %v

What it means

When Rule.UnmarshalJSON sees type == "alerting", it unmarshals the entry into an Alert; failure is wrapped as 'rule: alerting rule unmarshal' with the raw entry. The type dispatch succeeded but the alerting payload violates the Alert JSON schema (e.g. name/expr wrong types).

Solutions

  1. Fix the entry to match the Alert schema (string fields for name, query, etc.)
  2. Validate the whole rules file against the rulespb Alert JSON schema
  3. Re-export rules with a compatible tool version

Example fix

// before
{"type": "alerting", "alert": {"name": 42}}
// after
{"type": "alerting", "alert": {"name": "HighErrors", "expr": "up == 0"}}
Defensive patterns

Strategy: validation

Validate before calling

var probe struct {
    Type string `json:"type"`
    Alert struct {
        Name string `json:"name"`
        Expr string `json:"expr"`
    } `json:"alert"`
}
if err := json.Unmarshal(entry, &probe); err != nil || probe.Alert.Name == "" {
    return fmt.Errorf("not a valid alerting rule")
}

Try / catch

if err := json.Unmarshal(entry, &rule); err != nil {
    if strings.Contains(err.Error(), "alerting rule unmarshal") {
        log.Printf("bad alerting rule entry: %s", entry)
    }
    return err
}

Prevention

When it happens

Trigger: A rule entry with "type": "alerting" whose fields don't match the Alert struct — mistyped fields, missing required alert fields encoded with wrong JSON types, or mismatched schema versions.

Common situations: Rules exported by older/newer tooling; hand-edited alert rules; converting Prometheus YAML rules to JSON with incorrect types.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at pkg/rules/rulespb/custom.go:227

	decider := struct {
		Type string `json:"type"`
	}{}
	if err := json.Unmarshal(entry, &decider); err != nil {
		return errors.Wrapf(err, "rule: type field unmarshal: %v", string(entry))
	}

	switch strings.ToLower(decider.Type) {
	case "recording":
		r := &RecordingRule{}
		if err := json.Unmarshal(entry, r); err != nil {
			return errors.Wrapf(err, "rule: recording rule unmarshal: %v", string(entry))
		}

		m.Result = &Rule_Recording{Recording: r}
	case "alerting":
		r := &Alert{}
		if err := json.Unmarshal(entry, r); err != nil {
			return errors.Wrapf(err, "rule: alerting rule unmarshal: %v", string(entry))
		}

		m.Result = &Rule_Alert{Alert: r}
	case "":
		return errors.Errorf("rule: no type field provided: %v", string(entry))
	default:
		return errors.Errorf("rule: unknown type field provided %s; %v", decider.Type, string(entry))
	}
	return nil
}

func (m *Rule) MarshalJSON() ([]byte, error) {
	if r := m.GetRecording(); r != nil {
		return json.Marshal(struct {
			*RecordingRule
			Type string `json:"type"`
		}{
			RecordingRule: r,

View on GitHub (pinned to 35b8b99117)