VictoriaMetrics/VictoriaMetrics · error

missing tags

Error message

missing tags

What it means

This error comes from unmarshaling a single metric row in the VictoriaMetrics /api/v1/import JSON format. After successfully parsing the `metric` object's tags, the parser requires at least one tag; a row whose `metric` object produces zero tags (e.g. empty `{}` or a non-object metric) is rejected. Tags identify the time series, so a row without any tag cannot be stored.

Source

Thrown at lib/protoparser/vmimport/parser.go:73

	r.reset()
	v, err := tu.p.Parse(s)
	if err != nil {
		return fmt.Errorf("cannot parse json line: %w", err)
	}

	// Unmarshal tags
	metric := v.GetObject("metric")
	if metric == nil {
		return fmt.Errorf("missing `metric` object")
	}
	tagsStart := len(tu.tagsPool)
	if err := tu.unmarshalTags(metric); err != nil {
		return fmt.Errorf("cannot unmarshal `metric`: %w", err)
	}
	tags := tu.tagsPool[tagsStart:]
	r.Tags = tags[:len(tags):len(tags)]
	if len(r.Tags) == 0 {
		return fmt.Errorf("missing tags")
	}

	// Unmarshal values
	values := v.GetArray("values")
	if len(values) == 0 {
		return fmt.Errorf("missing `values` array")
	}
	for i, v := range values {
		f, err := v.Float64()
		if err != nil {
			// Fall back to parsing special values
			f, err = getSpecialFloat64(v)
			if err != nil {
				return fmt.Errorf("cannot unmarshal value at position %d: %w", i, err)
			}
		}
		r.Values = append(r.Values, f)
	}

View on GitHub (pinned to 5079fb58f1)

Solutions

  1. Ensure every row has a `metric` object with at least one key/value tag, e.g. {"metric":{"__name__":"cpu","host":"a"},"values":[1],"timestamps":[1700000000000]}
  2. Verify the client actually serializes the tags map (check it is not nil/empty before sending)
  3. Log the offending payload line and re-send with corrected tags; consider adding a `__name__` tag if the series only had tags in a different field

Example fix

// before
{"metric":{},"values":[1],"timestamps":[1700000000000]}
// after
{"metric":{"__name__":"cpu_usage","host":"node1"},"values":[1],"timestamps":[1700000000000]}
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate rows before sending
for _, row := range rows {
    if len(row.Tags) == 0 {
        return fmt.Errorf("row %q has no tags; every metric needs at least one tag (e.g. __name__)", row.MetricName)
    }
}

Type guard

func hasTags(m map[string]string) bool { return m != nil && len(m) > 0 }

Prevention

When it happens

Trigger: Posting JSON lines to /api/v1/import where a metric object is empty ({}), where the `metric` field is missing or not a JSON object, or where unmarshalTags succeeds but produces an empty tag list.

Common situations: Hand-written import payloads with placeholder `{}` metric objects; a client serializer dropping all tags when tag values are empty; batching code that builds rows from partially-filled structs where the tag map was never populated; format changes after upgrading VictoriaMetrics where `metric` was renamed.

Related errors


AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03). Data as JSON: /api/errors/79bc6c2377b5ea8c. Report an issue: GitHub.