{"record":{"id":"b95c0d848ac6ffa4","repo":"prometheus/node_exporter","slug":"failed-to-scan-dm-multipath-devices-w","errorCode":null,"errorMessage":"failed to scan DM-multipath devices: %w","messagePattern":"failed to scan DM-multipath devices: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/dmmultipath_linux.go","lineNumber":104,"sourceCode":"\tfs, err := blockdevice.NewFS(*procPath, *sysPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to open sysfs: %w\", err)\n\t}\n\n\treturn &dmMultipathCollector{\n\t\tfs:     fs,\n\t\tlogger: logger,\n\t}, nil\n}\n\nfunc (c *dmMultipathCollector) Update(ch chan<- prometheus.Metric) error {\n\tdevices, err := c.fs.DMMultipathDevices()\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) || errors.Is(err, os.ErrPermission) {\n\t\t\tc.logger.Debug(\"Could not read DM-multipath devices\", \"err\", err)\n\t\t\treturn ErrNoData\n\t\t}\n\t\treturn fmt.Errorf(\"failed to scan DM-multipath devices: %w\", err)\n\t}\n\n\tfor _, dev := range devices {\n\t\tch <- prometheus.MustNewConstMetric(dmmultipathDeviceInfo, prometheus.GaugeValue, 1,\n\t\t\tdev.Name, dev.SysfsName, dev.UUID)\n\n\t\tactive := 0.0\n\t\tif !dev.Suspended {\n\t\t\tactive = 1.0\n\t\t}\n\t\tch <- prometheus.MustNewConstMetric(dmmultipathDeviceActive, prometheus.GaugeValue, active, dev.Name, dev.SysfsName)\n\t\tch <- prometheus.MustNewConstMetric(dmmultipathDeviceSizeBytes, prometheus.GaugeValue, float64(dev.SizeBytes), dev.Name, dev.SysfsName)\n\n\t\tvar activePaths, failedPaths float64\n\t\tfor _, p := range dev.Paths {\n\t\t\tif isPathActive(p.State) {\n\t\t\t\tactivePaths++\n\t\t\t} else {","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/dmmultipath_linux.go#L86-L122","documentation":"Update calls fs.DMMultipathDevices() to scan /sys/block/dm-* for multipath devices. ErrNotExist and ErrPermission are demoted to debug logs plus ErrNoData, but any other error aborts the scrape with this wrapped message. It signals an unexpected failure enumerating device-mapper block devices rather than their simple absence.","triggerScenarios":"DMMultipathDevices() returns a non-ErrNotExist/ErrPermission error during a scrape: I/O error reading /sys/block, glob failure, or unexpected filesystem error while reading dm-* attributes (name, uuid).","commonSituations":"Failing underlying storage while dm devices are being removed/reconfigured mid-scan; sysfs returning EIO for a stale dm device; exotic LSM/SELinux denials reported as other errno values.","solutions":["Check kernel logs (dmesg) for device-mapper or sysfs I/O errors at scrape time","Inspect the wrapped cause (%w) to identify the failing device or errno","Re-scan; transient races during dm device teardown usually clear on the next scrape","Verify /sys/block is healthy and dm-* entries are not stale (dmsetup ls)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(\"/sys/block\"); err != nil {\n    // /sys/block unreadable; expect ErrNoData from dm-multipath collector\n}","typeGuard":null,"tryCatchPattern":"if err := c.Update(ch); err != nil {\n    if errors.Is(err, collector.ErrNoData) {\n        // tolerated: dm devices absent or unreadable\n    } else if strings.Contains(err.Error(), \"failed to scan DM-multipath devices\") {\n        // inspect wrapped cause; often transient during device teardown — retry next scrape\n    }\n}","preventionTips":["Treat ErrNoData as benign on hosts without multipath","Retry scrapes before alerting; dm teardown races are transient","Monitor dmesg for device-mapper errors correlated with scrape failures"],"tags":["linux","sysfs","dm-multipath","scrape"],"backgroundTag":"file-read-failed","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"}