{"record":{"id":"47b127dc7c5ff414","repo":"dani-garcia/vaultwarden","slug":"you-should-not-define-both-key-and-key-file","errorCode":null,"errorMessage":"You should not define both {key} and {key_file}!","messagePattern":"You should not define both (.+?) and (.+?)!","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/util.rs","lineNumber":440,"sourceCode":"    T: FromStr,\n{\n    if let Some(Ok(value)) = string.map(|s| s.as_ref().parse::<T>()) {\n        Some(value)\n    } 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\"];","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/dani-garcia/vaultwarden/blob/cc67d644f62605cb46f4d16c4a2eed1a861cc8bb/src/util.rs#L422-L458","documentation":"Vaultwarden reads optional config values either directly from the environment variable KEY or from a file path stored in KEY_FILE (a common Docker secrets pattern). This panic fires when both KEY and KEY_FILE are defined for the same key, because the source of truth would be ambiguous.","triggerScenarios":"Calling get_env(\"X\") or get_env_bool(\"X\") when both X and X_FILE are set in the process environment, e.g. DATABASE_URL plus DATABASE_URL_FILE, or ADMIN_TOKEN plus ADMIN_TOKEN_FILE.","commonSituations":"Docker Compose setups where an env var is inherited from the shell AND a secret file is mounted via env_file; Kubernetes deployments mixing ConfigMap env vars with mounted secret files; lingering exported variables in the container image.","solutions":["Unset the plain env var and keep only KEY_FILE (preferred for secrets)","or delete the *_FILE variable and set the value directly in KEY","Inspect the container environment (docker exec env / kubectl describe pod) to find where both are defined","Remove the duplicate from docker-compose environment/env_file or the image's ENV directives"],"exampleFix":"// before\ndocker run -e ADMIN_TOKEN=secret -e ADMIN_TOKEN_FILE=/run/secrets/admin_token vaultwarden\n// after\ndocker run -e ADMIN_TOKEN_FILE=/run/secrets/admin_token vaultwarden","handlingStrategy":"validation","validationCode":"const K = 'ADMIN_TOKEN';\nconst hasEnv = K in process.env;\nconst hasFile = `${K}_FILE` in process.env;\nif (hasEnv && hasFile) throw new Error(`Define only one of ${K} or ${K}_FILE`);","typeGuard":"function envSource(key) {\n  const v = process.env[key], f = process.env[`${key}_FILE`];\n  if (v !== undefined && f !== undefined) return null; // conflict\n  return v !== undefined ? { kind: 'env', value: v } : f !== undefined ? { kind: 'file', path: f } : { kind: 'absent' };\n}","tryCatchPattern":null,"preventionTips":["Pick one convention (env var OR *_FILE secret) per key across all deployments","Audit docker-compose env/env_file blocks for *_FILE duplicates","In Kubernetes, don't mix ConfigMap env vars with secret-file mounts for the same key","Document which keys support the _FILE pattern"],"tags":["env","configuration","docker-secrets"],"backgroundTag":"conflicting-config-options","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"}