prometheus/node_exporter · error
failed to parse textfile data from
Error message
failed to parse textfile data from %q: %w
What it means
After opening the file, processFile parses it with expfmt's TextParser (TextToMetricFamilies). Any exposition-format syntax error — bad metric names, malformed HELP/TYPE lines, invalid samples — is wrapped as this error, and the whole file's metrics are discarded.
Solutions
- Validate the file locally: promtool check metrics < /path/to/file.prom before/after writing
- Write atomically (temp file + rename) so the parser never sees a half-written file
- Fix the producing script's exposition format (correct TYPE/HELP lines, quoted label values, numeric values)
- Check for editor/tooling artifacts like BOM or CRLF if files are edited by hand
Example fix
// before: writing garbage value
echo 'my_metric{host="x"} abc' > foo.prom
// after
echo 'my_metric{host="x"} 1' > foo.prom Defensive patterns
Strategy: validation
Validate before calling
out, err := exec.Command("promtool", "check", "metrics", filepath.Join(dir, name)).CombinedOutput()
if err != nil { /* invalid exposition format — fix writer before deploy */ } Try / catch
if err := coll.Update(ch); err != nil {
if strings.Contains(err.Error(), "failed to parse textfile data") {
log.Warn("malformed .prom file", "err", err)
}
} Prevention
- Run promtool check metrics in CI or in the writing script before publishing
- Use temp-file + atomic rename so partial files are never parsed
- Escape label values correctly (no raw newlines/quotes)
- Avoid manual edits and editors that add BOM/CRLF to .prom files
When it happens
Trigger: A file in the textfile directory contains text that is not valid Prometheus exposition format: unterminated HELP strings, non-numeric sample values, duplicate metric names with conflicting types, trailing garbage.
Common situations: Scripts writing metrics with broken escaping (newlines in labels); partially written files read mid-write (no atomic rename); Windows line endings or BOM from editors; writing the 'node_exporter' metric namespace causing conflicts is fine but malformed TYPE lines are not.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- textfile contains unsupported client-side timestamps…
- unknown metric type
- collector returned no data
- invalid value in meminfo
- invalid line in meminfo
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/b8f41b1073902963.
Report an issue: GitHub.
Appendix: source
Thrown at collector/textfile.go:299
prometheus.GaugeValue, errVal,
)
return nil
}
// processFile processes a single file, returning its modification time on success.
func (c *textFileCollector) processFile(dir, name string) (*time.Time, map[string]*dto.MetricFamily, error) {
path := filepath.Join(dir, name)
f, err := os.Open(path)
if err != nil {
return nil, nil, fmt.Errorf("failed to open textfile data file %q: %w", path, err)
}
defer f.Close()
parser := expfmt.NewTextParser(model.UTF8Validation)
families, err := parser.TextToMetricFamilies(f)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse textfile data from %q: %w", path, err)
}
if hasTimestamps(families) {
return nil, nil, fmt.Errorf("textfile %q contains unsupported client-side timestamps, skipping entire file", path)
}
// Only stat the file once it has been parsed and validated, so that
// a failure does not appear fresh.
stat, err := f.Stat()
if err != nil {
return nil, families, fmt.Errorf("failed to stat %q: %w", path, err)
}
t := stat.ModTime()
return &t, families, nil
}
// hasTimestamps returns true when metrics contain unsupported timestamps.View on GitHub (pinned to 17ddd77c59)