{"record":{"id":"15ffecfb12863fe8","repo":"astrid-runtime/astrid","slug":"stopped-astrid-durable-root-cannot-provision-runti","errorCode":null,"errorMessage":"stopped Astrid durable root cannot provision runtime identity sidecars","messagePattern":"stopped Astrid durable root cannot provision runtime identity sidecars","errorType":"validation","errorClass":"std::io::Error::InvalidData","httpStatus":null,"severity":"error","filePath":"crates/astrid-core/src/dirs.rs","lineNumber":464,"sourceCode":"\n        match std::fs::symlink_metadata(self.root()) {\n            Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidData,\n                    format!(\n                        \"Astrid home without a layout sentinel is redirected or not a directory: {}\",\n                        self.root().display()\n                    ),\n                ));\n            },\n            Ok(_) => {},\n            Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(()),\n            Err(error) => return Err(error),\n        }\n        crate::platform_fs::validate_private_directory(self.root())?;\n\n        if self.validate_fresh_root_entries()? == UnsentinelledRootState::StoppedVolume {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                \"stopped Astrid durable root cannot provision runtime identity sidecars\",\n            ));\n        }\n        Ok(())\n    }\n\n    fn validate_fresh_root_entries(&self) -> io::Result<UnsentinelledRootState> {\n        let mut entries = self.root().read_dir()?.collect::<Result<Vec<_>, _>>()?;\n        entries.sort_by_key(std::fs::DirEntry::file_name);\n        if entries.len() == 1 && entries[0].file_name() == std::ffi::OsStr::new(\"keys\") {\n            self.validate_runtime_key_bootstrap(&entries[0].path())?;\n            return Ok(UnsentinelledRootState::RuntimeKeyBootstrap);\n        }\n        let mut state = UnsentinelledRootState::Empty;\n        for entry in entries {\n            let path = entry.path();\n            if entry.file_name() != std::ffi::OsStr::new(\"astrid.volume\") {","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-core/src/dirs.rs#L446-L482","documentation":"Thrown by validate_runtime_identity_provisioning when validate_fresh_root_entries reports the root is in the StoppedVolume state — a detached/stopped durable-volume representation that cannot safely hold runtime identity sidecars (private keys).","triggerScenarios":"Calling validate_runtime_identity_provisioning (via prepare or sign_archive_with_runtime_key_in_home) when the durable root is the stopped volume-only representation, after validate_private_directory succeeds.","commonSituations":"Attempting to sign or provision keys while the backing durable volume is unmounted/stopped, e.g. running the signing flow on a machine or container where the volume was detached.","solutions":["Start/attach the durable volume that backs the Astrid root, then retry","Run the provisioning/signing operation on the host where the volume is active","Move ASTRID_HOME to a live local directory if volume-backed provisioning is not intended"],"exampleFix":"// before: volume stopped\n./sign-archive --home /mnt/volume/.astrid  # fails\n// after\nvolume start astrid-durable\n./sign-archive --home /mnt/volume/.astrid","handlingStrategy":"validation","validationCode":"if !volume_is_active(astrid_home) {\n    eprintln!(\"start/attach the durable volume before provisioning identity\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"match dirs.validate_runtime_identity_provisioning() {\n    Err(e) if e.to_string().contains(\"stopped Astrid durable root\") => {\n        volume_start(); // then retry\n    },\n    other => other?,\n}","preventionTips":["Ensure the durable volume is mounted/started before signing or prepare","Add health checks for volume availability in automation","Avoid scheduling identity provisioning on hosts without the active volume"],"tags":["state","storage","signing"],"backgroundTag":"invalid-state-transition","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}