{"record":{"id":"218250c54d3ab185","repo":"prometheus/node_exporter","slug":"failed-to-open-procfs-w-218250","errorCode":null,"errorMessage":"failed to open procfs: %w","messagePattern":"failed to open procfs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/meminfo_linux.go","lineNumber":34,"sourceCode":"package collector\n\nimport (\n\t\"fmt\"\n\t\"log/slog\"\n\n\t\"github.com/prometheus/procfs\"\n)\n\ntype meminfoCollector struct {\n\tfs     procfs.FS\n\tlogger *slog.Logger\n}\n\n// NewMeminfoCollector returns a new Collector exposing memory stats.\nfunc NewMeminfoCollector(logger *slog.Logger) (Collector, error) {\n\tfs, err := procfs.NewFS(*procPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to open procfs: %w\", err)\n\t}\n\n\treturn &meminfoCollector{\n\t\tlogger: logger,\n\t\tfs:     fs,\n\t}, nil\n}\n\nfunc (c *meminfoCollector) getMemInfo() (map[string]float64, error) {\n\tmeminfo, err := c.fs.Meminfo()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get memory info: %w\", err)\n\t}\n\n\tmetrics := make(map[string]float64)\n\n\tif meminfo.ActiveBytes != nil {\n\t\tmetrics[\"Active_bytes\"] = float64(*meminfo.ActiveBytes)","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/meminfo_linux.go#L16-L52","documentation":"NewMeminfoCollector builds a procfs filesystem handle from the --path.procfs flag (default /proc) via procfs.NewFS. If procfs cannot be mounted/opened at that path, the collector cannot be constructed and this wrapped error is returned at startup. It almost always means the procfs mount point is missing, not mounted, or the configured path is wrong.","triggerScenarios":"procfs.NewFS(*procPath) returns an error because the directory given by --path.procfs does not exist, is not a directory, is unreadable, or /proc is not mounted — typically in containers without /proc mounted or with a custom --path.procfs value pointing at a nonexistent location.","commonSituations":"Running node_exporter in a Docker/container runtime where /proc was not bind-mounted; running in a chroot or minimal image lacking /proc; typo in --path.procfs; running inside restricted namespaces (e.g. some CI sandboxes) where procfs is hidden.","solutions":["Ensure /proc is mounted in the container/environment (docker run without disabling /proc, or explicitly mount it: -v /proc:/proc:ro)","Verify the --path.procfs flag points to a mounted procfs directory (check with `ls <path>/meminfo`)","If running in a restrictive sandbox, run the collector with the privileges/namespace access needed to read /proc","Disable the meminfo collector (e.g. build with the nomeminfo tag or --collector.meminfo flag off) if /proc is intentionally unavailable"],"exampleFix":"// before (container start)\ndocker run --rm my-node-exporter\n// after\ndocker run --rm -v /proc:/host/proc:ro my-node-exporter --path.procfs=/host/proc","handlingStrategy":"validation","validationCode":"const procPath = \"/proc\"\nif info, err := os.Stat(filepath.Join(procPath, \"meminfo\")); err != nil || info.IsDir() {\n    log.Fatalf(\"procfs not available at %s: %v\", procPath, err)\n}","typeGuard":null,"tryCatchPattern":"collector, err := NewMeminfoCollector(logger)\nif err != nil {\n    logger.Error(\"failed to init meminfo collector; is /proc mounted?\", \"err\", err)\n    return err\n}","preventionTips":["Always mount /proc (read-only) when running in containers","Explicitly pass --path.procfs when the exporter runs against a host-mounted /proc","Verify the mount before starting the exporter in minimal images/chroots"],"tags":["linux","procfs","startup","configuration"],"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"}