prometheus/node_exporter · info · ErrNoData

collector returned no data

Error message

collector returned no data

What it means

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).

Solutions

  1. Treat this as benign: check collector.IsNoDataError(err) (or errors.Is) and skip/skip-alert instead of failing
  2. If you expected data, verify the subsystem actually exists (e.g. /sys/fs/bcachefs) and that kernel/driver support is present
  3. Disable the collector for hosts without the subsystem (e.g. --collector.bcachefs or the relevant collector flag) to silence it

Example fix

// before
if err := c.Update(ch); err != nil {
    return err
}
// after
if err := c.Update(ch); err != nil {
    if collector.IsNoDataError(err) {
        return nil // nothing to collect on this host
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: before treating an Update error as fatal, pre-check the subsystem exists
if _, err := os.Stat("/sys/fs/bcachefs"); os.IsNotExist(err) {
    // subsystem absent; skip collection without surfacing an error
}

Type guard

func isNoData(err error) bool { return errors.Is(err, collector.ErrNoData) }

Try / catch

if err := c.Update(ch); err != nil {
    if collector.IsNoDataError(err) {
        c.logger.Debug("no data for subsystem; skipping")
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07). Data as JSON: /api/errors/573a876abde6dbcd. Report an issue: GitHub.

Appendix: source

Thrown at collector/collector.go:195

}

// Collector is the interface a collector has to implement.
type Collector interface {
	// Get new metrics and expose them via prometheus registry.
	Update(ch chan<- prometheus.Metric) error
}

type typedDesc struct {
	desc      *prometheus.Desc
	valueType prometheus.ValueType
}

func (d *typedDesc) mustNewConstMetric(value float64, labels ...string) prometheus.Metric {
	return prometheus.MustNewConstMetric(d.desc, d.valueType, value, labels...)
}

// ErrNoData indicates the collector found no data to collect, but had no other error.
var ErrNoData = errors.New("collector returned no data")

func IsNoDataError(err error) bool {
	return err == ErrNoData
}

// pushMetric helps construct and convert a variety of value types into Prometheus float64 metrics.
func pushMetric(ch chan<- prometheus.Metric, fieldDesc *prometheus.Desc, value any, valueType prometheus.ValueType, labelValues ...string) {
	var fVal float64
	switch val := value.(type) {
	case uint8:
		fVal = float64(val)
	case uint16:
		fVal = float64(val)
	case uint32:
		fVal = float64(val)
	case uint64:
		fVal = float64(val)
	case int64:

View on GitHub (pinned to 17ddd77c59)