VictoriaMetrics/VictoriaMetrics · error

cannot parse timestamp from %q: %w

Error message

cannot parse timestamp from %q: %w

What it means

parseRows (invoked from Unmarshal / UnmarshalDetectHeader) processes each CSV row against the parsed ColumnDescriptors. When the descriptor has a ParseTimestamp function and calling it on the row's time column fails, the row is marked with this error wrapping the underlying cause and the row is rejected.

Source

Thrown at lib/protoparser/csvimport/parser.go:145

		var r Row
		col := uint(0)
		metrics = metrics[:0]
		tagsLen := len(tags)
		for sc.NextColumn() {
			if col >= uint(len(cds)) {
				// Skip superfluous column.
				continue
			}
			cd := &cds[col]
			col++
			if cd.isEmpty() || sc.Column == "" {
				// Ignore empty column.
				continue
			}
			if parseTimestamp := cd.ParseTimestamp; parseTimestamp != nil {
				timestamp, err := parseTimestamp(sc.Column)
				if err != nil {
					sc.Error = fmt.Errorf("cannot parse timestamp from %q: %w", sc.Column, err)
					break
				}
				r.Timestamp = timestamp
				continue
			}
			if tagName := cd.TagName; tagName != "" {
				tags = append(tags, Tag{
					Key:   tagName,
					Value: sc.Column,
				})
				continue
			}
			metricName := cd.MetricName
			if metricName == "" {
				logger.Panicf("BUG: unexpected empty MetricName")
			}
			value, err := fastfloat.Parse(sc.Column)
			if err != nil {

View on GitHub (pinned to 5079fb58f1)

Solutions

  1. Read the wrapped cause in sc.Error (e.g. 'cannot parse time in RFC3339 from %q') to identify the exact failing cell and fix it or its format
  2. Align the time entry format in ParseColumnDescriptors with the actual data format in the CSV
  3. Pre-filter/normalize rows: drop or repair rows with empty or sentinel timestamps before calling Unmarshal
  4. Dry-run parse the time column with the expected parser to find every bad row before import

Example fix

// before: data is RFC3339 but spec is unix_ms
cds, _ := csvimport.ParseColumnDescriptors("time:unix_ms,metric")
rows, err := csvimport.Unmarshal(data, cds) // fails
// after
cds, _ := csvimport.ParseColumnDescriptors("time:rfc3339,metric")
rows, err := csvimport.Unmarshal(data, cds)
Defensive patterns

Strategy: try-catch

Validate before calling

func dryRunTimestamps(data []byte, cds []csvimport.ColumnDescriptor) error {
	for i, row := range strings.Split(string(data), "\n") {
		cols := strings.Split(row, ",")
		for _, cd := range cds {
			if cd.ParseTimestamp != nil {
				idx := int(cd.ColumnPos()) - 1 // adapt to your descriptor API
				if idx >= 0 && idx < len(cols) {
					if _, err := cd.ParseTimestamp(cols[idx]); err != nil {
						return fmt.Errorf("row %d: %w", i+1, err)
					}
				}
			}
		}
	}
	return nil
}

Try / catch

rows, err := csvimport.Unmarshal(data, cds)
if err != nil {
	var scErr string
	if strings.Contains(err.Error(), "cannot parse timestamp from") {
		// log the row, quarantine it, and continue with valid rows instead of aborting
		_ = scErr
	}
}

Prevention

When it happens

Trigger: Calling csvimport.Unmarshal/UnmarshalDetectHeader on data whose time column cannot be parsed by the configured format — e.g. spec says time:unix_ms but rows contain RFC3339 strings; this error is the outer wrapper that surfaces errors 1013/1015/1016/1017/1018.

Common situations: Mixed-format timestamp columns across rows (some numeric, some formatted); empty timestamp cells; CSV data changed upstream (new exporter emits different format) while the spec stayed the same; rows with sentinel timestamps ('N/A', 0-filled).

Related errors


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