atuinsh/atuin · error

could not register user due to version mismatch

Error message

could not register user due to version mismatch

What it means

After posting to `/register`, the client calls `ensure_version`, which compares the server's reported version against the client's. If the server version header is missing/too old (version negotiation fails), registration is aborted with this message because old servers cannot support the current registration flow.

Source

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

    let mut headers = extra_headers_map(extra_headers)?;
    headers.insert(USER_AGENT, APP_USER_AGENT.parse()?);
    headers.insert(ATUIN_HEADER_VERSION, ATUIN_CARGO_VERSION.parse()?);

    let client = client_builder(extra_headers).build()?;

    let url = address.append(["user", username])?;
    let resp = client.get(url).headers(headers.clone()).send().await?;

    if resp.status().is_success() {
        bail!("username already in use");
    }

    let url = address.append(["register"])?;
    let resp = client.post(url).headers(headers).json(&map).send().await?;
    let resp = handle_resp_error(resp).await?;

    if !ensure_version(&resp)? {
        bail!("could not register user due to version mismatch");
    }

    let session = resp.json::<RegisterResponse>().await?;
    Ok(session)
}

#[instrument(level = "trace", skip_all, err)]
pub async fn login(
    address: &Url,
    req: LoginRequest,
    extra_headers: &HashMap<String, String>,
) -> Result<LoginResponse> {
    let url = address.append(["login"])?;
    let client = client_builder(extra_headers).build()?;

    let mut headers = extra_headers_map(extra_headers)?;
    headers.insert(USER_AGENT, APP_USER_AGENT.parse()?);

View on GitHub (pinned to c0c717ab04)

Solutions

  1. Upgrade the sync server to a version matching or exceeding the client
  2. Check the server version header is being emitted (reverse proxy stripping headers?)
  3. Downgrade the client if you must keep the old server (not recommended)

Example fix

// before
docker run ghcr.io/atuinsh/atuin:v17 server start
// after
docker pull ghcr.io/atuinsh/atuin:latest && docker run ghcr.io/atuinsh/atuin:latest server start
Defensive patterns

Strategy: validation

Validate before calling

// check server version before registering
let resp = client.get(format!("{address}/health")).send().await?;
let server_ver = resp.headers().get("x-atuin-version")
    .and_then(|v| v.to_str().ok())
    .ok_or_else(|| eyre!("server missing version header"))?;
if Version::parse(server_ver)?.major < ATUIN_VERSION.major {
    eprintln!("upgrade the sync server before registering");
    return Ok(());
}

Try / catch

match register(...).await {
    Err(e) if e.to_string().contains("version mismatch") => {
        eprintln!("upgrade your atuin sync server, then retry");
    }
    other => other?,
}

Prevention

When it happens

Trigger: `atuin register` against a sync server whose `x-atuin-version` header indicates an incompatible (older) major version, or whose version cannot be validated by `ensure_version`

Common situations: Self-hosted server not upgraded after a breaking client release; running an old atuin-server docker image while the CLI is current

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/745e553b692735ba. Report an issue: GitHub.