{"record":{"id":"d7cb87b561e80b10","repo":"dani-garcia/vaultwarden","slug":"failed-to-load-key-e","errorCode":null,"errorMessage":"Failed to load {key}: {e:?}","messagePattern":"Failed to load (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/util.rs","lineNumber":444,"sourceCode":"    } else {\n        None\n    }\n}\n\n//\n// Env methods\n//\npub fn get_env_str_value(key: &str) -> Option<String> {\n    let key_file = format!(\"{key}_FILE\");\n    let value_from_env = env::var(key);\n    let value_file = env::var(&key_file);\n\n    match (value_from_env, value_file) {\n        (Ok(_), Ok(_)) => panic!(\"You should not define both {key} and {key_file}!\"),\n        (Ok(v_env), Err(_)) => Some(v_env),\n        (Err(_), Ok(v_file)) => match std::fs::read_to_string(v_file) {\n            Ok(content) => Some(content.trim().to_owned()),\n            Err(e) => panic!(\"Failed to load {key}: {e:?}\"),\n        },\n        _ => None,\n    }\n}\n\npub fn get_env<V>(key: &str) -> Option<V>\nwhere\n    V: FromStr,\n{\n    try_parse_string(get_env_str_value(key))\n}\n\npub fn get_env_bool(key: &str) -> Option<bool> {\n    const TRUE_VALUES: &[&str] = &[\"true\", \"t\", \"yes\", \"y\", \"1\"];\n    const FALSE_VALUES: &[&str] = &[\"false\", \"f\", \"no\", \"n\", \"0\"];\n\n    match get_env_str_value(key) {\n        Some(val) if TRUE_VALUES.contains(&val.to_lowercase().as_ref()) => Some(true),","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/dani-garcia/vaultwarden/blob/cc67d644f62605cb46f4d16c4a2eed1a861cc8bb/src/util.rs#L426-L462","documentation":"When a config key is supplied only via KEY_FILE, Vaultwarden reads the file with fs::read_to_string at startup. This panic fires if that file cannot be read (missing, unreadable, or invalid path), aborting configuration loading.","triggerScenarios":"X_FILE points to a non-existent file, the process lacks read permission, the path is a directory, or the secret mount failed (empty/failed volume mount in Docker/Kubernetes).","commonSituations":"Kubernetes secret not mounted before startup; Docker secrets typo in the mount path; SELinux/AppArmor blocking access; file deleted by tmpfs cleanup; path containing trailing whitespace or unexpanded $VARS.","solutions":["Verify the file exists and is readable by the Vaultwarden process user (ls -l, stat)","Check container volume/secrets mounts (docker inspect, kubectl get pod -o yaml)","Fix the X_FILE path in your env configuration; use an absolute path","Test with: cat $X_FILE inside the container to reproduce the exact OS error shown in the panic"],"exampleFix":"// before\ndocker-compose: ADMIN_TOKEN_FILE: ./secrets/admin_token.txt  (not copied into image)\n// after\nvolumes:\n  - ./secrets/admin_token.txt:/run/secrets/admin_token:ro\nenvironment:\n  ADMIN_TOKEN_FILE: /run/secrets/admin_token","handlingStrategy":"validation","validationCode":"const path = process.env.ADMIN_TOKEN_FILE;\nif (path) {\n  const fs = require('fs');\n  if (!fs.existsSync(path) || !fs.statSync(path).isFile()) throw new Error(`${path} missing or not a file`);\n  fs.accessSync(path, fs.constants.R_OK);\n}","typeGuard":"function readableFile(p) { try { return typeof p === 'string' && require('fs').statSync(p).isFile() && require('fs').accessSync(p, require('fs').constants.R_OK) === undefined; } catch { return false; } }","tryCatchPattern":null,"preventionTips":["Mount secret files at stable absolute paths (e.g. /run/secrets/)","Ensure the container user has read permission on mounted secrets","Test secret mounts in CI before deploy (cat the file in an init step)","Avoid relative paths and unexpanded variables in *_FILE values"],"tags":["env","file-io","docker-secrets"],"backgroundTag":"file-read-failed","analyzedSha":"cc67d644f62605cb46f4d16c4a2eed1a861cc8bb","analyzedAt":"2026-09-19T08:28:46.370Z","contentChangedAt":"2026-09-19T08:28:46.370Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}