{"record":{"id":"5a49dff322ca5ce3","repo":"clockworklabs/SpacetimeDB","slug":"aborted-5a49df","errorCode":null,"errorMessage":"Aborted","messagePattern":"Aborted","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"crates/cli/src/subcommands/server.rs","lineNumber":275,"sourceCode":"\n            Ok(true)\n        }\n    } else {\n        println!(\"No saved fingerprint for server {nick_or_host}. New fingerprint:\\n{new_fing}\");\n\n        config.set_server_fingerprint(server, new_fing)?;\n\n        Ok(true)\n    }\n}\n\npub async fn exec_fingerprint(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::Error> {\n    let server = args.get_one::<String>(\"server\").unwrap().as_str();\n    let force = args.get_flag(\"force\");\n\n    if update_server_fingerprint(&mut config, Some(server)).await? {\n        if !y_or_n(force, \"Continue?\")? {\n            anyhow::bail!(\"Aborted\");\n        }\n\n        config.save();\n    }\n\n    Ok(())\n}\n\npub async fn exec_ping(config: Config, args: &ArgMatches) -> Result<(), anyhow::Error> {\n    let server = args.get_one::<String>(\"server\").unwrap().as_str();\n    let url = config.get_host_url(Some(server))?;\n\n    let builder = reqwest::Client::new().get(format!(\"{url}/v1/ping\").as_str());\n    let response = builder.send().await?;\n\n    match response.status() {\n        reqwest::StatusCode::OK => {\n            println!(\"Server is online: {url}\");","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/cli/src/subcommands/server.rs#L257-L293","documentation":"`spacetime server fingerprint` calls `update_server_fingerprint`, which contacts the server and compares its presented fingerprint against the one stored in config. If the fingerprint changed (the function returns true after storing the new one), the CLI prompts 'Continue?' — the server's identity differs from what you pinned, which can be benign re-deployment or an interception. Declining bails with 'Aborted' before `config.save()`.","triggerScenarios":"The server's TLS/host key legitimately rotated (redeploy, container rebuild, ephemeral dev keys) or was never pinned for this server; the user answers anything other than `y`, or stdin closes, at the Continue? prompt; `--force` was not passed.","commonSituations":"Local `spacetimedb` node restarted with a regenerated key; testnet/maincloud cert rotation; shared dev server re-provisioned; security-conscious users declining when the change is unexpected.","solutions":["If you expect the change (dev restart, announced rotation), re-run and answer `y`, or pass `--force` to skip the prompt — the new fingerprint is then saved","If the change is unexpected, verify the server out-of-band before trusting it — a changed fingerprint can indicate interception","Pin afresh by removing and re-adding the server with fingerprint verification if the stored state is confusing","For local servers with unstable keys, add with `--no-fingerprint` to avoid TOFU churn"],"exampleFix":"# before\nspacetime server fingerprint local   # fingerprint changed -> declined -> Aborted\n# after\nspacetime server fingerprint local --force","handlingStrategy":"try-catch","validationCode":"# Non-interactive: decide ahead of time to trust fingerprint changes\nspacetime server fingerprint myserver --force   # or omit --force to gate on the prompt","typeGuard":null,"tryCatchPattern":"// Guard automation: only auto-accept fingerprint changes for local dev servers\nif is_local(server) { run(\"spacetime server fingerprint\", [\"--force\"]) } else { prompt_human(server) }","preventionTips":["Treat unexpected fingerprint changes on remote servers as a security event; verify out-of-band before continuing","Use `--no-fingerprint` for ephemeral local servers to avoid constant TOFU prompts","Pin fingerprints again after known server re-provisioning"],"tags":["spacetimedb","fingerprint","server-identity","confirmation","security"],"backgroundTag":"server-fingerprint-mismatch","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}