louislam/uptime-kuma · error · Error
Failed to read _FILE at
Error message
Failed to read ${envName}_FILE at ${fileValue}: ${err.message} What it means
Thrown by getEnvOrFile(envName) when the *_FILE path is set but fs.readFileSync fails (the secrets file does not exist, is unreadable, or wrong permissions). The original fs error message is appended for diagnosis.
Solutions
- Verify the file exists inside the container at the exact *_FILE path (docker exec ls -l /run/secrets/<name>).
- Fix the secret name/mount so the file is present and readable by the kuma process uid.
- Correct the *_FILE environment value to the real path, or unset it and use the direct variable instead.
Example fix
# before UPTIME_KUMA_DB_PASSWORD_FILE=/run/secrets/db_pass # (file not mounted) # after volumes: - db_password_secret:/run/secrets/db_password:ro UPTIME_KUMA_DB_PASSWORD_FILE=/run/secrets/db_password
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: ensure secret files are readable
const fs = require("fs");
function assertSecretReadable(fileEnv) {
const p = process.env[fileEnv];
if (p && !fs.existsSync(p)) {
throw new Error(`${fileEnv} -> ${p} missing; mount the secret.`);
}
}
assertSecretReadable("UPTIME_KUMA_DB_PASSWORD_FILE"); Type guard
function secretFileOk(fileEnv) {
const p = process.env[fileEnv];
return !p || (fs.existsSync(p) && fs.accessSync.bind(fs, p, fs.constants.R_OK) || true);
} Try / catch
try {
boot();
} catch (e) {
if (/Failed to read .*_FILE at/.test(e.message)) {
haltWithHint("Secret file path unreadable: " + e.message);
} else throw e;
} Prevention
- Verify secret mounts with docker exec ls -l before starting.
- Run the kuma container as a uid that can read /run/secrets.
- Keep *_FILE paths consistent across environments.
When it happens
Trigger: UPTIME_KUMA_DB_*_FILE points at a path that the process cannot open: secret not mounted in the container, file removed, path typo, or restrictive file mode. Triggered during setup-database bootstrap.
Common situations: Docker secret named differently than the path; Kubernetes secret not mounted because the deployment spec references a missing secret; running as a uid without read permission on the secrets file; bind-mount path differs between host and container.
Related errors
- Both and _FILE are set. Please use only one.
- Invalid db-config.json, type must be a string
- Unknown Database type
- Aggregate table migration is already in progress
- Failed to load docker host config
AI-assisted analysis of louislam/uptime-kuma@6b5ea01557 (2026-08-12).
Data as JSON: /api/errors/3270bce88fdd87a5.
Report an issue: GitHub.
Appendix: source
Thrown at server/setup-database.js:31
* Reads a configuration value from an environment variable or a Docker secrets file.
* If both the direct env var and the _FILE variant are set, an error is thrown.
* @param {string} envName The base name of the environment variable (e.g., "UPTIME_KUMA_DB_PASSWORD")
* @returns {string|undefined} The value from the env var, file contents (trimmed), or undefined if neither is set
* @throws {Error} If both the direct env var and the _FILE variant are set
*/
function getEnvOrFile(envName) {
const directValue = process.env[envName];
const fileValue = process.env[envName + "_FILE"];
if (directValue && fileValue) {
throw new Error(`Both ${envName} and ${envName}_FILE are set. Please use only one.`);
}
if (fileValue) {
try {
return fs.readFileSync(fileValue, "utf8").trim();
} catch (err) {
throw new Error(`Failed to read ${envName}_FILE at ${fileValue}: ${err.message}`);
}
}
return directValue;
}
/**
* A standalone express app that is used to setup a database
* It is used when db-config.json and kuma.db are not found or invalid
* Once it is configured, it will shut down and start the main server
*/
class SetupDatabase {
/**
* Show Setup Page
* @type {boolean}
*/
needSetup = true;
/**View on GitHub (pinned to 6b5ea01557)