{"record":{"id":"2daf6d7faa11231e","repo":"henrygd/beszel","slug":"data-directory-not-found","errorCode":null,"errorMessage":"data directory not found","messagePattern":"data directory not found","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/data_dir.go","lineNumber":67,"sourceCode":"\t\texists, _ := directoryExists(path)\n\t\tif exists {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := os.MkdirAll(path, 0755); err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Verify the created directory is actually writable\n\t\twritable, _ := directoryIsWritable(path)\n\t\tif !writable {\n\t\t\tcontinue\n\t\t}\n\n\t\treturn path, nil\n\t}\n\n\treturn \"\", errors.New(\"data directory not found\")\n}\n\nfunc isValidDataDir(path string, createIfNotExists bool) (bool, error) {\n\texists, err := directoryExists(path)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tif !exists {\n\t\tif !createIfNotExists {\n\t\t\treturn false, nil\n\t\t}\n\t\tif err = os.MkdirAll(path, 0755); err != nil {\n\t\t\treturn false, err\n\t\t}\n\t}\n\n\t// Always check if the directory is writable","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/agent/data_dir.go#L49-L85","documentation":"GetDataDir scans a list of candidate directories and returns the first one that passes isValidDataDir. When every candidate fails validation (or none exist), it gives up and returns this sentinel error. It means the agent could not locate (or create) a usable data directory for storing its fingerprint and other state.","triggerScenarios":"Calling agent.GetDataDir() when all candidate paths either do not exist and createIfNotExists is false, exist but fail directoryExists checks, fail permission checks (not writable/readable), or the candidate list itself is empty.","commonSituations":"Running the agent as a service under a user whose HOME differs from the interactive user; read-only or missing /etc/beszel or ~/.beszel directories; restricted container images where the expected data path was never created; permission changes after package upgrades.","solutions":["Create the expected data directory and grant the agent's user read/write permissions (e.g. mkdir -p /etc/beszel && chown beszel:beszel /etc/beszel).","Check the HOME/working directory environment of the service unit or container so the candidate path actually exists for the running user.","Run the agent once in the foreground with debug logs to see which candidate paths are tried and why each fails isValidDataDir.","If using a container, mount a persistent volume at the expected data path so it survives restarts."],"exampleFix":"// before (dir missing, agent runs as 'beszel' user)\n$ ls /etc/beszel\nls: cannot access '/etc/beszel': No such file or directory\n\n// after\n$ sudo mkdir -p /etc/beszel\n$ sudo chown beszel:beszel /etc/beszel\n$ sudo systemctl restart beszel-agent","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(\"/etc/beszel\"); err != nil {\n    log.Printf(\"data dir missing: %v — create it and grant write access to the agent user\", err)\n}","typeGuard":null,"tryCatchPattern":"dir, err := agent.GetDataDir()\nif err != nil {\n    if err.Error() == \"data directory not found\" {\n        os.MkdirAll(expectedDir, 0o755)\n        dir, err = agent.GetDataDir()\n    }\n    if err != nil {\n        log.Fatalf(\"no usable data dir: %v\", err)\n    }\n}","preventionTips":["Provision the data directory in packaging/systemd unit (StateDirectory= or ExecStartPre=mkdir -p).","Run the agent under a dedicated user with ownership of the data directory.","Mount a persistent volume at the data path in container deployments."],"tags":["filesystem","configuration","data-directory","permissions"],"backgroundTag":"data-directory-not-found","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}