{"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/900007c48045867e7f44b0f9bc55ad9dbe99ee0d/crates/atuin-client/src/api_client.rs#L194-L230","documentation":"When a server response carries no version header at all, `ensure_version` cannot verify compatibility and bails. The message indicates the server predates version reporting or is unhealthy — syncing cannot be validated.","triggerScenarios":"register, login, or record_status against a server that omits the `x-atuin-version` header in its response.","commonSituations":"`sync_address` accidentally pointed at the wrong host/port (another web app answering), a very old Atuin server (<v0.6 era), or a proxy stripping custom headers.","solutions":["Verify `sync_address` points at a real Atuin sync server","Check for a reverse proxy stripping `x-atuin-*` headers and allowlist them","Upgrade a self-hosted server that is too old to report versions","Test with `curl -sD - <sync-address>` to see whether the header is present"],"exampleFix":"// before (proxy strips headers)\nproxy_set_header X-Atuin-Version \"\";\n// after\nproxy_pass_header X-Atuin-Version;","handlingStrategy":"validation","validationCode":"// verify the endpoint is an Atuin server before calling register/login/record_status\nlet resp = reqwest::get(sync_address).await?;\nif resp.headers().get(\"x-atuin-version\").is_none() {\n    eprintln!(\"endpoint does not report an Atuin version — check sync_address and proxy\");\n    return Ok(());\n}","typeGuard":"fn server_reports_version(headers: &reqwest::header::HeaderMap) -> bool {\n    headers.contains_key(\"x-atuin-version\")\n}","tryCatchPattern":"match client.record_status().await {\n    Err(e) if e.to_string().contains(\"not reporting its version\") => {\n        eprintln!(\"check sync_address / proxy headers / server version\");\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["Confirm sync_address resolves to the Atuin server","Allowlist x-atuin-* headers through reverse proxies","Keep self-hosted servers current enough to emit version headers"],"tags":["http","headers","versioning","network"],"backgroundTag":"unexpected-response-shape","analyzedSha":"900007c48045867e7f44b0f9bc55ad9dbe99ee0d","analyzedAt":"2026-09-19T12:52:51.491Z","contentChangedAt":"2026-09-19T12:52:51.491Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}