{"record":{"id":"46c119b55a75aa4f","repo":"atuinsh/atuin","slug":"server-not-reporting-its-version-it-is-either-too","errorCode":null,"errorMessage":"Server not reporting its version: it is either too old or unhealthy","messagePattern":"Server not reporting its version: it is either too old or unhealthy","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin-client/src/api_client.rs","lineNumber":212,"sourceCode":"\n    let index = resp.json::<IndexResponse>().await?;\n    let version = Version::parse(index.version.as_str())?;\n\n    Ok(version)\n}\n\npub fn ensure_version(response: &Response) -> Result<bool> {\n    let version = response.headers().get(ATUIN_HEADER_VERSION);\n\n    let version = if let Some(version) = version {\n        match version.to_str() {\n            Ok(v) => Version::parse(v),\n            Err(e) => {\n                bail!(\"failed to parse server version: {:?}\", e);\n            }\n        }\n    } else {\n        bail!(\"Server not reporting its version: it is either too old or unhealthy\");\n    }?;\n\n    // If the client is newer than the server\n    if version.major < ATUIN_VERSION.major {\n        println!(\n            \"Atuin version mismatch! In order to successfully sync, the server needs to run a \\\n             newer version of Atuin\"\n        );\n        println!(\"Client: {ATUIN_CARGO_VERSION}\");\n        println!(\"Server: {version}\");\n\n        return Ok(false);\n    }\n\n    Ok(true)\n}\n\n#[instrument(level = \"trace\", skip_all, err)]","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/atuinsh/atuin/blob/c0c717ab04c881764bcad4b3d169a507e2432643/crates/atuin-client/src/api_client.rs#L194-L230","documentation":"`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.","triggerScenarios":"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","commonSituations":"Pointing the client at a stale self-hosted image, a health-check/placeholder endpoint, or an nginx config that drops custom headers","solutions":["Verify the URL points at a real atuin sync server (curl -i and look for x-atuin-version)","Upgrade the sync server to a recent version","Fix proxy config to pass through the x-atuin-version header"],"exampleFix":"// before\n# nginx\ncustom_headers off;\n// after\n# nginx\nproxy_pass_header x-atuin-version;","handlingStrategy":"validation","validationCode":"// confirm the endpoint is an atuin server before sync calls\nlet health = client.get(format!(\"{address}/health\")).send().await?;\nif health.headers().get(\"x-atuin-version\").is_none() {\n    eprintln!(\"endpoint is not a version-reporting atuin server\");\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"match ensure_version(&resp) {\n    Err(e) if e.to_string().contains(\"not reporting its version\") => {\n        eprintln!(\"server is too old or unhealthy; upgrade/restart it\");\n    }\n    other => other?,\n}","preventionTips":["Point sync.url only at genuine atuin sync servers","Upgrade ancient servers before connecting new clients","Audit proxy configs so x-atuin-version is never stripped"],"tags":["version-mismatch","http","sync"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"c0c717ab04c881764bcad4b3d169a507e2432643","analyzedAt":"2026-09-12T07:40:01.341Z","contentChangedAt":"2026-09-12T07:40:01.341Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}