{"record":{"id":"53e89c06cf019a4f","repo":"zeroclaw-labs/zeroclaw","slug":"the-backend-does-not-support-automatic-key-ge","errorCode":null,"errorMessage":"The '{}' backend does not support automatic key generation. Create the master key externally, then verify access with `zeroclaw quickstart`.","messagePattern":"The '(.+?)' backend does not support automatic key generation\\. Create the master key externally, then verify access with `zeroclaw quickstart`\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-config/src/secrets.rs","lineNumber":74,"sourceCode":"/// Object-safe, single-trait design.  Only `with_key`, `backend_name`,\n/// and `provisioning_state` are required; `initialize` has a default\n/// error for backends that cannot create keys locally.\npub trait KeySource: Debug + Send + Sync {\n    /// Run `f` with a reference to the 256-bit master key.  The\n    /// reference is only valid during the call.\n    fn with_key(&self, f: &mut dyn FnMut(&[u8; 32]) -> Result<()>) -> Result<()>;\n\n    /// Human-readable label for diagnostic messages.\n    fn backend_name(&self) -> &'static str;\n\n    /// Local-only provisioning check — MUST NOT run scripts or\n    /// prompt for user input.\n    fn provisioning_state(&self) -> ProvisioningState;\n\n    /// Generate fresh key material.  Default error for backends\n    /// that cannot create keys locally.\n    fn initialize(&self) -> Result<()> {\n        anyhow::bail!(\n            \"The '{}' backend does not support automatic key generation. \\\n             Create the master key externally, then verify access with \\\n             `zeroclaw quickstart`.\",\n            self.backend_name()\n        )\n    }\n}\n\n/// File-system backed key source.  Reads/writes a 32-byte hex-encoded\n/// key at the given path (default: `~/.zeroclaw/.secret_key`, 0600).\n#[derive(Debug, Clone)]\npub struct FileKeySource {\n    key_path: PathBuf,\n}\n\nimpl FileKeySource {\n    pub fn new(key_path: PathBuf) -> Self {\n        Self { key_path }","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-config/src/secrets.rs#L56-L92","documentation":"KeySource::initialize() has a default implementation that errors this way, and only backends that can create key material locally (like the file backend) override it. ZeroClaw calls initialize() during quickstart/provisioning when provisioning_state() reports NeedsInitialization; for externally managed backends (externally provisioned key sources), automatic generation is intentionally unsupported and this default fires. The master key must be created out-of-band, then `zeroclaw quickstart` verifies access to it.","triggerScenarios":"Programmatically calling KeySource::initialize() on a custom or external backend that does not override the default; running a provisioning/quickstart flow against a key source whose material lives outside this process (KMS, secret manager, operator-managed file); treating ExternallyProvisioned like NeedsInitialization and calling initialize().","commonSituations":"Writing a custom KeySource (e.g., vault or HSM backed) and forgetting to implement initialize(); deployment automation calling initialize() unconditionally on all backends; org policy forbidding locally generated keys, hitting the deliberate refusal.","solutions":["Create/provision the master key externally per your backend's process (e.g., generate 32 random bytes and place them where the backend reads them)","Then run `zeroclaw quickstart` to verify the backend can access the key","If you own the backend and local generation is acceptable, override initialize() in your KeySource impl"],"exampleFix":"// before: custom backend relying on default initialize()\nimpl KeySource for VaultKeySource {\n    fn with_key(&self, f: &mut dyn FnMut(&[u8; 32]) -> Result<()>) -> Result<()> { /* ... */ }\n    fn backend_name(&self) -> &'static str { \"vault\" }\n    fn provisioning_state(&self) -> ProvisioningState { ProvisioningState::NeedsInitialization }\n}\n\n// after: implement local generation\nimpl KeySource for VaultKeySource {\n    fn initialize(&self) -> Result<()> {\n        let key: [u8; 32] = rand::random();\n        self.store_key(&key) // backend-specific write\n    }\n    // ...same remaining methods\n}","handlingStrategy":"type-guard","validationCode":"use zeroclaw_config::secrets::ProvisioningState;\nfn can_auto_initialize(src: &dyn KeySource) -> bool {\n    // Only attempt initialize() when the backend says local init is expected;\n    // ExternallyProvisioned backends reject it by design.\n    matches!(src.provisioning_state(), ProvisioningState::NeedsInitialization)\n}","typeGuard":"fn needs_local_init(state: ProvisioningState) -> bool {\n    matches!(state, ProvisioningState::NeedsInitialization)\n}\n\nif needs_local_init(source.provisioning_state()) {\n    source.initialize()?; // safe: backend opted into local generation\n}","tryCatchPattern":"if let Err(e) = source.initialize() {\n    if e.to_string().contains(\"does not support automatic key generation\") {\n        eprintln!(\"provision the master key externally, then run `zeroclaw quickstart`\");\n    }\n    return Err(e);\n}","preventionTips":["Always branch on provisioning_state() (Initialized / NeedsInitialization / ExternallyProvisioned) instead of calling initialize() blindly","When implementing custom KeySource backends, override initialize() only if local generation is genuinely supported","Document for each deployment backend whether keys are self-managed or externally provisioned"],"tags":["secrets","key-management","provisioning","quickstart","trait-default"],"backgroundTag":"unsupported-backend-operation","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}