atuinsh/atuin · error

Server not reporting its version: it is either too old or un

Error message

Server not reporting its version: it is either too old or unhealthy

What it means

`ensure_version` requires every sync server response to carry the `x-atuin-version` header. If it is absent, the server is assumed to be pre-version-negotiation (very old) or broken, and the client bails with this message.

Source

Thrown at crates/atuin-client/src/api_client.rs:212

    let index = resp.json::<IndexResponse>().await?;
    let version = Version::parse(index.version.as_str())?;

    Ok(version)
}

pub fn ensure_version(response: &Response) -> Result<bool> {
    let version = response.headers().get(ATUIN_HEADER_VERSION);

    let version = if let Some(version) = version {
        match version.to_str() {
            Ok(v) => Version::parse(v),
            Err(e) => {
                bail!("failed to parse server version: {:?}", e);
            }
        }
    } else {
        bail!("Server not reporting its version: it is either too old or unhealthy");
    }?;

    // If the client is newer than the server
    if version.major < ATUIN_VERSION.major {
        println!(
            "Atuin version mismatch! In order to successfully sync, the server needs to run a \
             newer version of Atuin"
        );
        println!("Client: {ATUIN_CARGO_VERSION}");
        println!("Server: {version}");

        return Ok(false);
    }

    Ok(true)
}

#[instrument(level = "trace", skip_all, err)]

View on GitHub (pinned to c0c717ab04)

Solutions

  1. Verify the URL points at a real atuin sync server (curl -i and look for x-atuin-version)
  2. Upgrade the sync server to a recent version
  3. Fix proxy config to pass through the x-atuin-version header

Example fix

// before
# nginx
custom_headers off;
// after
# nginx
proxy_pass_header x-atuin-version;
Defensive patterns

Strategy: validation

Validate before calling

// confirm the endpoint is an atuin server before sync calls
let health = client.get(format!("{address}/health")).send().await?;
if health.headers().get("x-atuin-version").is_none() {
    eprintln!("endpoint is not a version-reporting atuin server");
    return Ok(());
}

Try / catch

match ensure_version(&resp) {
    Err(e) if e.to_string().contains("not reporting its version") => {
        eprintln!("server is too old or unhealthy; upgrade/restart it");
    }
    other => other?,
}

Prevention

When it happens

Trigger: register/login/record_status against a server that does not send `x-atuin-version`: very old atuin-server, an unrelated service at that address, or a proxy stripping the header

Common situations: Pointing the client at a stale self-hosted image, a health-check/placeholder endpoint, or an nginx config that drops custom headers

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of atuinsh/atuin@c0c717ab04 (2026-09-12). Data as JSON: /api/errors/46c119b55a75aa4f. Report an issue: GitHub.