{"record":{"id":"573a876abde6dbcd","repo":"prometheus/node_exporter","slug":"collector-returned-no-data","errorCode":null,"errorMessage":"collector returned no data","messagePattern":"collector returned no data","errorType":"exception","errorClass":"ErrNoData","httpStatus":null,"severity":"info","filePath":"collector/collector.go","lineNumber":195,"sourceCode":"}\n\n// Collector is the interface a collector has to implement.\ntype Collector interface {\n\t// Get new metrics and expose them via prometheus registry.\n\tUpdate(ch chan<- prometheus.Metric) error\n}\n\ntype typedDesc struct {\n\tdesc      *prometheus.Desc\n\tvalueType prometheus.ValueType\n}\n\nfunc (d *typedDesc) mustNewConstMetric(value float64, labels ...string) prometheus.Metric {\n\treturn prometheus.MustNewConstMetric(d.desc, d.valueType, value, labels...)\n}\n\n// ErrNoData indicates the collector found no data to collect, but had no other error.\nvar ErrNoData = errors.New(\"collector returned no data\")\n\nfunc IsNoDataError(err error) bool {\n\treturn err == ErrNoData\n}\n\n// pushMetric helps construct and convert a variety of value types into Prometheus float64 metrics.\nfunc pushMetric(ch chan<- prometheus.Metric, fieldDesc *prometheus.Desc, value any, valueType prometheus.ValueType, labelValues ...string) {\n\tvar fVal float64\n\tswitch val := value.(type) {\n\tcase uint8:\n\t\tfVal = float64(val)\n\tcase uint16:\n\t\tfVal = float64(val)\n\tcase uint32:\n\t\tfVal = float64(val)\n\tcase uint64:\n\t\tfVal = float64(val)\n\tcase int64:","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/collector.go#L177-L213","documentation":"ErrNoData is a sentinel error (collector/collector.go) meaning a collector ran successfully but found nothing to expose, e.g. the bcachefs sysfs path does not exist or the stats list is empty. It exists so the exporter can distinguish 'nothing to collect' from a real failure; node_exporter's Update/handleErr path treats it specially and does not log it as a hard error. Callers can detect it with collector.IsNoDataError or errors.Is(err, collector.ErrNoData).","triggerScenarios":"A collector's Update() returns ErrNoData directly: bcachefs_linux.go returns it when /sys/fs/bcachefs does not exist (os.IsNotExist) or when the retrieved stats slice is empty. Any code path documented to 'return ErrNoData' when the subsystem is absent.","commonSituations":"Running node_exporter on a machine without the bcachefs filesystem mounted or kernel support; a container or minimal VM lacking the expected /sys entries; collecting from a host where the subsystem is configured but has zero instances/devices.","solutions":["Treat this as benign: check collector.IsNoDataError(err) (or errors.Is) and skip/skip-alert instead of failing","If you expected data, verify the subsystem actually exists (e.g. /sys/fs/bcachefs) and that kernel/driver support is present","Disable the collector for hosts without the subsystem (e.g. --collector.bcachefs or the relevant collector flag) to silence it"],"exampleFix":"// before\nif err := c.Update(ch); err != nil {\n    return err\n}\n// after\nif err := c.Update(ch); err != nil {\n    if collector.IsNoDataError(err) {\n        return nil // nothing to collect on this host\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// Go: before treating an Update error as fatal, pre-check the subsystem exists\nif _, err := os.Stat(\"/sys/fs/bcachefs\"); os.IsNotExist(err) {\n    // subsystem absent; skip collection without surfacing an error\n}","typeGuard":"func isNoData(err error) bool { return errors.Is(err, collector.ErrNoData) }","tryCatchPattern":"if err := c.Update(ch); err != nil {\n    if collector.IsNoDataError(err) {\n        c.logger.Debug(\"no data for subsystem; skipping\")\n        return nil\n    }\n    return err\n}","preventionTips":["Always special-case ErrNoData via errors.Is/IsNoDataError — it is informational, not a failure","Gate collectors by whether the underlying sysfs/sysctl subsystem exists on the host","Alert on missing series with absence-based alerts, not on scrape errors"],"tags":["sentinel-error","no-data","collector","prometheus"],"backgroundTag":"empty-result-set","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"}