{"record":{"id":"cb3cf29315e48546","repo":"prometheus/node_exporter","slug":"failed-to-open-sysfs-w-cb3cf2","errorCode":null,"errorMessage":"failed to open sysfs: %w","messagePattern":"failed to open sysfs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/dmi.go","lineNumber":42,"sourceCode":"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/prometheus/procfs/sysfs\"\n)\n\ntype dmiCollector struct {\n\tinfoDesc *prometheus.Desc\n\tvalues   []string\n}\n\nfunc init() {\n\tregisterCollector(\"dmi\", defaultEnabled, NewDMICollector)\n}\n\n// NewDMICollector returns a new Collector exposing DMI information.\nfunc NewDMICollector(logger *slog.Logger) (Collector, error) {\n\tfs, err := sysfs.NewFS(*sysPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to open sysfs: %w\", err)\n\t}\n\n\tdmi, err := fs.DMIClass()\n\tif err != nil {\n\t\tif errors.Is(err, os.ErrNotExist) {\n\t\t\tlogger.Debug(\"Platform does not support Desktop Management Interface (DMI) information\", \"err\", err)\n\t\t\tdmi = &sysfs.DMIClass{}\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"failed to read Desktop Management Interface (DMI) information: %w\", err)\n\t\t}\n\t}\n\n\tvar labels, values []string\n\tfor label, value := range map[string]*string{\n\t\t\"bios_date\":         dmi.BiosDate,\n\t\t\"bios_release\":      dmi.BiosRelease,\n\t\t\"bios_vendor\":       dmi.BiosVendor,\n\t\t\"bios_version\":      dmi.BiosVersion,","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/dmi.go#L24-L60","documentation":"NewDMICollector wraps any failure from sysfs.NewFS(*sysPath) with \"failed to open sysfs\". sysfs.NewFS validates that the sysfs mount point exists and is readable, so this error means the configured --path.sysfs root could not be used as an fs.FS. It aborts collector construction, so the DMI collector is never registered.","triggerScenarios":"node_exporter started with --path.sysfs pointing at a nonexistent directory, an unreadable path, or a path that is not a directory; sysfs.NewFS returns an error for any reason other than being handed a usable filesystem root.","commonSituations":"Running node_exporter in a container without /sys mounted; a typo'd or overridden --path.sysfs flag; sysfs bind-mounted read-only into an unusual location; running on a system where /sys is absent.","solutions":["Verify the --path.sysfs flag points to a mounted, readable sysfs (default /sys)","Mount sysfs into the container: docker run -v /sys:/sys:ro","Create or correct the directory and check permissions with ls -ld /sys","If the platform genuinely has no DMI, rely on the ErrNotExist path being handled downstream and fix the path rather than disabling the collector"],"exampleFix":"// before\nnode_exporter --path.sysfs=/mnt/wrong-sys\n// after\nnode_exporter --path.sysfs=/sys","handlingStrategy":"validation","validationCode":"if st, err := os.Stat(sysPath); err != nil || !st.IsDir() {\n    // sysfs path unusable; fix --path.sysfs before starting\n}","typeGuard":null,"tryCatchPattern":"c, err := collector.NewDMICollector(logger)\nif err != nil {\n    if errors.Is(err, os.ErrNotExist) { /* skip DMI collector */ } else { return err }\n}","preventionTips":["Always mount /sys (read-only) when running node_exporter in containers","Never override --path.sysfs without verifying the target with ls -ld","Include a startup smoke test that lists /sys before launching exporters"],"tags":["linux","sysfs","dmi","filesystem"],"backgroundTag":"file-open-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"}