{"record":{"id":"61cdaf8bcca237de","repo":"netdata/netdata","slug":"geoip-failed-to-stat-database","errorCode":null,"errorMessage":"geoip: failed to stat database '{}': {}","messagePattern":"geoip: failed to stat database '(.+?)': (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/crates/netflow-plugin/src/enrichment/data/geoip/files.rs","lineNumber":60,"sourceCode":"            .collect::<Result<Vec<_>>>()?,\n        geo: geo_paths\n            .iter()\n            .map(|path| read_geoip_file_signature(path, optional))\n            .collect::<Result<Vec<_>>>()?,\n    })\n}\n\npub(crate) fn read_geoip_file_signature(\n    path: &str,\n    optional: bool,\n) -> Result<Option<GeoIpFileSignature>> {\n    let metadata = match fs::metadata(path) {\n        Ok(metadata) => metadata,\n        Err(_) if optional => {\n            return Ok(None);\n        }\n        Err(err) => {\n            return Err(anyhow::anyhow!(\n                \"geoip: failed to stat database '{}': {}\",\n                path,\n                err\n            ));\n        }\n    };\n\n    let modified = match metadata.modified() {\n        Ok(time) => time,\n        Err(err) if optional => {\n            tracing::warn!(\n                \"geoip: failed to read modification time for optional database '{}': {}\",\n                path,\n                err\n            );\n            return Ok(None);\n        }\n        Err(err) => {","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/netdata/netdata/blob/4864de85e26f6734d92cfc27ccbeff5921f49938/src/crates/netflow-plugin/src/enrichment/data/geoip/files.rs#L42-L78","documentation":"read_geoip_file_signature calls fs::metadata on each configured GeoIP database to build a change-detection signature (mtime + size). For a required database, any metadata failure (usually ENOENT or EACCES) returns this error instead of a signature.","triggerScenarios":"A required GeoIP database path that cannot be stat'ed: file removed between config check and signature read, path on an unmounted network share, or directory traversal denied. Optional databases skip the signature with Ok(None) instead.","commonSituations":"Database deleted or rotated (GeoLite2 update scripts that replace files) while the agent runs; NFS/SMB mount drops; symlink to a missing target; path with a missing parent directory.","solutions":["Confirm the path exists at the moment of the error: ls -l <path> and stat <path>","Check parent-directory execute permissions for the netdata user","If the file is replaced during updates, point config at a stable path and atomically rename new files into place","Mark the database optional if transient absence is acceptable"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"stat /usr/share/GeoIP/GeoLite2-ASN.mmdb || echo \"cannot stat GeoIP DB - fix path/mount before starting agent\"","typeGuard":null,"tryCatchPattern":"Wrap enrichment startup: on stat failure, retry after a short delay (covers mounts settling) then report and run without GeoIP if configured optional.","preventionTips":["Keep mmdb files on local disk, not removable/network mounts","Use atomic replace during DB rotation so stat never sees a missing file","Add monitoring on the DB path (file exists check)"],"tags":["netflow","geoip","filesystem","stat","config"],"backgroundTag":null,"analyzedSha":"4864de85e26f6734d92cfc27ccbeff5921f49938","analyzedAt":"2026-08-15T09:12:38.226Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}