{"record":{"id":"b8f41b1073902963","repo":"prometheus/node_exporter","slug":"failed-to-parse-textfile-data-from-q-w","errorCode":null,"errorMessage":"failed to parse textfile data from %q: %w","messagePattern":"failed to parse textfile data from %q: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/textfile.go","lineNumber":299,"sourceCode":"\t\tprometheus.GaugeValue, errVal,\n\t)\n\n\treturn nil\n}\n\n// processFile processes a single file, returning its modification time on success.\nfunc (c *textFileCollector) processFile(dir, name string) (*time.Time, map[string]*dto.MetricFamily, error) {\n\tpath := filepath.Join(dir, name)\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to open textfile data file %q: %w\", path, err)\n\t}\n\tdefer f.Close()\n\n\tparser := expfmt.NewTextParser(model.UTF8Validation)\n\tfamilies, err := parser.TextToMetricFamilies(f)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse textfile data from %q: %w\", path, err)\n\t}\n\n\tif hasTimestamps(families) {\n\t\treturn nil, nil, fmt.Errorf(\"textfile %q contains unsupported client-side timestamps, skipping entire file\", path)\n\t}\n\n\t// Only stat the file once it has been parsed and validated, so that\n\t// a failure does not appear fresh.\n\tstat, err := f.Stat()\n\tif err != nil {\n\t\treturn nil, families, fmt.Errorf(\"failed to stat %q: %w\", path, err)\n\t}\n\n\tt := stat.ModTime()\n\treturn &t, families, nil\n}\n\n// hasTimestamps returns true when metrics contain unsupported timestamps.","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/textfile.go#L281-L317","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: writing garbage value\necho 'my_metric{host=\"x\"} abc' > foo.prom\n// after\necho 'my_metric{host=\"x\"} 1' > foo.prom","handlingStrategy":"validation","validationCode":"out, err := exec.Command(\"promtool\", \"check\", \"metrics\", filepath.Join(dir, name)).CombinedOutput()\nif err != nil { /* invalid exposition format — fix writer before deploy */ }","typeGuard":null,"tryCatchPattern":"if err := coll.Update(ch); err != nil {\n    if strings.Contains(err.Error(), \"failed to parse textfile data\") {\n        log.Warn(\"malformed .prom file\", \"err\", err)\n    }\n}","preventionTips":["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"],"tags":["textfile","parsing","prometheus","exposition-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"17ddd77c59ba27e1508e9f7894b1e55b44d6aed3","analyzedAt":"2026-09-07T17:54:06.211Z","contentChangedAt":"2026-09-07T17:54:06.211Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}