{"record":{"id":"71802e133e406be4","repo":"prometheus/node_exporter","slug":"failed-to-open-procfs-w-71802e","errorCode":null,"errorMessage":"failed to open procfs: %w","messagePattern":"failed to open procfs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/zoneinfo_linux.go","lineNumber":42,"sourceCode":"\nconst zoneinfoSubsystem = \"zoneinfo\"\n\ntype zoneinfoCollector struct {\n\tgaugeMetricDescs   map[string]*prometheus.Desc\n\tcounterMetricDescs map[string]*prometheus.Desc\n\tlogger             *slog.Logger\n\tfs                 procfs.FS\n}\n\nfunc init() {\n\tregisterCollector(\"zoneinfo\", defaultDisabled, NewZoneinfoCollector)\n}\n\n// NewZoneinfoCollector returns a new Collector exposing zone stats.\nfunc NewZoneinfoCollector(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\treturn &zoneinfoCollector{\n\t\tgaugeMetricDescs:   createGaugeMetricDescriptions(),\n\t\tcounterMetricDescs: createCounterMetricDescriptions(),\n\t\tlogger:             logger,\n\t\tfs:                 fs,\n\t}, nil\n}\n\nfunc (c *zoneinfoCollector) Update(ch chan<- prometheus.Metric) error {\n\tmetrics, err := c.fs.Zoneinfo()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"couldn't get zoneinfo: %w\", err)\n\t}\n\tfor _, metric := range metrics {\n\t\tnode := metric.Node\n\t\tzone := metric.Zone\n\t\tmetricStruct := reflect.ValueOf(metric)","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/zoneinfo_linux.go#L24-L60","documentation":"NewZoneinfoCollector initializes a procfs client rooted at the --path.procfs flag value; if procfs.NewFS fails (directory missing or unreadable) the collector cannot read /proc/zoneinfo, so it returns this wrapped error instead of a collector. Node_exporter surfaces it at startup as a failed enabled collector.","triggerScenarios":"Starting node_exporter with the zoneinfo collector enabled while *procPath points to a nonexistent or non-procfs directory (e.g. --path.procfs=/proc on a non-Linux container, or a bad chroot/mount).","commonSituations":"Running the exporter in a container without /proc mounted; a typo in --path.procfs; collecting from a remote filesystem mount that lacks /proc/zoneinfo; restricted mount namespaces.","solutions":["Verify the path given to --path.procfs exists and contains procfs files (zoneinfo)","Ensure /proc is mounted in the container (--volume /proc:/host/proc:ro and --path.procfs=/host/proc)","Disable the zoneinfo collector (--collector.zoneinfo) if the environment has no zone stats","Check mount namespace/permissions so the process can read the procfs directory"],"exampleFix":"// before\nnode_exporter --collector.zoneinfo --path.procfs=/host/proc\n# fails if /host/proc is not mounted\n// after\nnode_exporter --collector.zoneinfo --path.procfs=/proc\n# or mount: docker run -v /proc:/host/proc:ro ...","handlingStrategy":"try-catch","validationCode":"if st, err := os.Stat(*procPath); err != nil || !st.IsDir() {\n    // do not enable the zoneinfo collector\n}","typeGuard":null,"tryCatchPattern":"collector, err := NewZoneinfoCollector(logger)\nif err != nil {\n    logger.Warn(\"zoneinfo collector unavailable\", \"err\", err)\n    collector = nil\n}","preventionTips":["Mount /proc read-only into containers and point --path.procfs at it","Validate --path.procfs before enabling zoneinfo","Disable collectors unavailable in the runtime environment","Test collector enablement on the target OS/container image first"],"tags":["procfs","startup","zoneinfo","linux"],"backgroundTag":"file-not-found","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"}