{"record":{"id":"51496d4d37d06a44","repo":"prometheus/node_exporter","slug":"couldn-t-get-diskstats-w-51496d","errorCode":null,"errorMessage":"couldn't get diskstats: %w","messagePattern":"couldn't get diskstats: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/diskstats_linux.go","lineNumber":266,"sourceCode":"\t\t\t},\n\t\t},\n\t\tlogger: logger,\n\t}\n\n\t// Only enable getting device properties from udev if the directory is readable.\n\tif stat, err := os.Stat(*udevDataPath); err != nil || !stat.IsDir() {\n\t\tlogger.Error(\"Failed to open directory, disabling udev device properties\", \"path\", *udevDataPath)\n\t} else {\n\t\tcollector.getUdevDeviceProperties = getUdevDeviceProperties\n\t}\n\n\treturn &collector, nil\n}\n\nfunc (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {\n\tdiskStats, err := c.fs.ProcDiskstats()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"couldn't get diskstats: %w\", err)\n\t}\n\n\tfor _, stats := range diskStats {\n\t\tdev := stats.DeviceName\n\t\tif c.deviceFilter.ignored(dev) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Only fetch udev device properties when udev is available\n\t\t// to avoid unnecessary file I/O.\n\t\tvar info udevInfo\n\t\tif c.getUdevDeviceProperties != nil {\n\t\t\tvar err error\n\t\t\tinfo, err = c.getUdevDeviceProperties(stats.MajorNumber, stats.MinorNumber)\n\t\t\tif err != nil {\n\t\t\t\tc.logger.Debug(\"Failed to parse udev info\", \"err\", err)\n\t\t\t}\n\t\t}","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/diskstats_linux.go#L248-L284","documentation":"The Linux diskstats collector's Update reads per-device I/O statistics from /proc/diskstats via c.fs.ProcDiskstats(). When that read/parse fails, Update returns \"couldn't get diskstats: %w\" and the scrape reports an error for that collector.","triggerScenarios":"Update() on Linux when ProcDiskstats() errors: /proc/diskstats missing or unreadable for the exporter process, or unexpected content the blockdevice parser cannot handle (very unusual kernel output).","commonSituations":"Containers without /proc mounted or with restrictive procfs hidepid settings; LSM/SELinux policies denying read of /proc/diskstats; heavily customized kernels producing unexpected diskstats formatting; chrooted environments lacking procfs.","solutions":["Check readability of /proc/diskstats as the node_exporter user: cat /proc/diskstats.","In containers, ensure /proc is mounted (e.g. -v /proc:/host/proc:ro with --path.procfs=/host/proc).","Check hidepid procfs mount options and LSM/audit logs for denials; grant read access to the exporter user.","Inspect the wrapped cause (%w); if parsing fails with a custom kernel, update node_exporter/procfs or file an upstream issue.","Disable diskstats collection if not needed (--no-collector.diskstats)."],"exampleFix":"// before (hidepid mount blocks read)\nproc /proc proc rw,hidepid=2 0 0\n// after (allow exporter group)\nproc /proc proc rw,hidepid=2,gid=<exporter_gid> 0 0","handlingStrategy":"try-catch","validationCode":"f, err := os.Open(\"/proc/diskstats\")\nif err != nil {\n    // /proc/diskstats unreadable; diskstats collector will fail\n} else {\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := coll.Update(ch); err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) && errors.Is(perr, fs.ErrPermission) {\n        log.Printf(\"diskstats blocked by permissions: %v\", perr)\n        return nil\n    }\n    return err\n}","preventionTips":["Ensure the exporter user/group can read /proc/diskstats (mind hidepid mount options).","Mount /proc into containers running node_exporter.","Check SELinux/AppArmor audit logs if reads are denied.","Monitor scrape error metrics to detect procfs regressions quickly."],"tags":["linux","procfs","diskstats","collector"],"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"}