astrid-runtime/astrid · error

gateway key at has wrong length ( bytes, expected 32) —…

Error message

gateway key at {} has wrong length ({} bytes, expected 32) — remove the file to regenerate

What it means

Corrupt-key guard in GatewaySigningKey::load_or_generate: the on-disk gateway signing key at keys/ under $ASTRID_HOME has the wrong byte length (expected 32), so it cannot be a valid key and startup refuses instead of using garbage material.

Solutions

  1. Remove the corrupt key file so the next startup regenerates a fresh 32-byte key
  2. Note that removing it invalidates previously issued tokens — plan re-authentication
  3. Check for disk corruption or partial writes that truncated the file
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at crates/astrid-gateway/src/state.rs:82 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/a1be64d4ac65b164. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-gateway/src/state.rs:82

    /// pattern: 0600 perms, atomic write-then-rename. Same path
    /// layout convention (`keys/` under `$ASTRID_HOME`).
    ///
    /// # Errors
    /// Returns an error if the keys directory can't be created,
    /// the on-disk key is corrupt (wrong length), or the file
    /// write fails.
    pub fn load_or_generate() -> anyhow::Result<Self> {
        use anyhow::Context as _;
        let home = astrid_core::dirs::AstridHome::resolve()
            .context("resolve $ASTRID_HOME for gateway signing key")?;
        let keys_dir = home.keys_dir();
        let key_path = keys_dir.join("gateway.ed25519");

        if key_path.exists() {
            let bytes = std::fs::read(&key_path)
                .with_context(|| format!("read gateway key at {}", key_path.display()))?;
            if bytes.len() != 32 {
                anyhow::bail!(
                    "gateway key at {} has wrong length ({} bytes, expected 32) — remove the file to regenerate",
                    key_path.display(),
                    bytes.len()
                );
            }
            let mut arr = [0u8; 32];
            arr.copy_from_slice(&bytes);
            let signer = SigningKey::from_bytes(&arr);
            let verifier = signer.verifying_key();
            return Ok(Self { signer, verifier });
        }

        // Generate fresh and persist atomically (write-then-rename
        // with 0600 perms, matching the kernel's runtime key flow).
        std::fs::create_dir_all(&keys_dir)
            .with_context(|| format!("create keys dir {}", keys_dir.display()))?;
        let fresh = Self::fresh();

View on GitHub (pinned to affd8760f4)