atuinsh/atuin · error
failed to parse server version
Error message
failed to parse server version: {:?} What it means
`ensure_version` reads the `x-atuin-version` header from a server response and parses it as a semver Version. If the header value is not valid UTF-8 (or the semver parse fails) the client bails with the underlying header conversion error debug-printed.
Solutions
- Inspect the header: `curl -sD - <sync-url> | grep -i atuin-version`
- Fix or remove the proxy rule that rewrites the header
- Point `sync_address` at a genuine Atuin server
- If parsing semver fails, upgrade the server to a version emitting valid semver
Defensive patterns
Strategy: type-guard
Validate before calling
// pre-flight: confirm the server emits a parseable semver version header
let resp = reqwest::get(format!("{sync_address}/health")).await?;
let v = resp.headers().get("x-atuin-version")
.and_then(|h| h.to_str().ok())
.ok_or("no version header")?;
semver::Version::parse(v)?; // fails fast here, not mid-login Type guard
fn valid_version_header(resp: &reqwest::Response) -> Option<semver::Version> {
resp.headers().get("x-atuin-version")
.and_then(|h| h.to_str().ok())
.and_then(|v| semver::Version::parse(v).ok())
} Prevention
- Check proxies don't rewrite custom headers
- Point sync_address only at genuine Atuin servers
- Validate server health before scripted register/login
When it happens
Trigger: Any API call routed through `ensure_version` (register, login, record_status) where the version header exists but its bytes are not valid UTF-8 or not valid semver.
Common situations: A reverse proxy injecting a malformed x-atuin-version header, a non-Atuin service on the sync URL, or a corrupted/modified server build.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Server not reporting its version: it is either too old or…
- Could not login due to version mismatch
- could not register user due to version mismatch
- current password is incorrect
- {}
AI-assisted analysis of atuinsh/atuin@900007c480 (2026-09-19).
Data as JSON: /api/errors/6153cf1f496e7e03.
Report an issue: GitHub.
Appendix: source
Thrown at crates/atuin-client/src/api_client.rs:208
let client = reqwest::Client::new();
let resp = client.get(url).header(USER_AGENT, APP_USER_AGENT).send().await?;
let resp = handle_resp_error(resp).await?;
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);
}
View on GitHub (pinned to 900007c480)