{"record":{"id":"a41251faefa5e3ce","repo":"tauri-apps/tauri","slug":"system-clock-is-incorrect","errorCode":null,"errorMessage":"system clock is incorrect","messagePattern":"system clock is incorrect","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tauri-cli/src/helpers/updater_signature.rs","lineNumber":191,"sourceCode":"  Ok(sk)\n}\n\n/// Gets the updater secret key from the given private key and password.\npub fn pub_key<S: AsRef<[u8]>>(public_key: S) -> crate::Result<PublicKey> {\n  let decoded_publick = decode_key(public_key).context(\"failed to decode base64 pubkey\")?;\n  let pk_box =\n    PublicKeyBox::from_string(&decoded_publick).context(\"failed to load updater pubkey\")?;\n  let pk = pk_box\n    .into_public_key()\n    .context(\"failed to convert updater pubkey\")?;\n  Ok(pk)\n}\n\nfn unix_timestamp() -> u64 {\n  let start = SystemTime::now();\n  let since_the_epoch = start\n    .duration_since(UNIX_EPOCH)\n    .expect(\"system clock is incorrect\");\n  since_the_epoch.as_secs()\n}\n\nfn open_data_file<P>(data_path: P) -> crate::Result<BufReader<File>>\nwhere\n  P: AsRef<Path>,\n{\n  let data_path = data_path.as_ref();\n  let file = OpenOptions::new()\n    .read(true)\n    .open(data_path)\n    .fs_context(\"failed to open data file\", data_path.to_path_buf())?;\n  Ok(BufReader::new(file))\n}\n\n#[cfg(test)]\nmod tests {\n  use super::*;","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/tauri-apps/tauri/blob/52e4b6e71d8632a7e648f866c442e287ecddee34/crates/tauri-cli/src/helpers/updater_signature.rs#L173-L209","documentation":"The tauri signer embeds a unix timestamp in updater signature keypairs/comments. unix_timestamp() computes SystemTime::now().duration_since(UNIX_EPOCH) and this expect panics when the duration is negative, i.e. the system clock currently reads a time before 1970-01-01 UTC. It is a pure environment problem, not a signing-key problem.","triggerScenarios":"Running `tauri signer generate` or `tauri signer sign` on a machine whose clock is set before the Unix epoch: dead CMOS battery resetting the RTC, a VM or container started without time synchronization, or a manually mis-set clock.","commonSituations":"Old headless servers / Raspberry Pi class hardware with failed RTC batteries; CI containers with broken time injection; freshly cloned VMs before guest additions sync time.","solutions":["Check the clock: run `date` and compare with real time.","Enable NTP synchronization: `sudo timedatectl set-ntp true` (or enable systemd-timesyncd/chrony) and verify with `timedatectl`.","For VMs/containers, enable host time sync (or set the correct time manually) and re-run the signer command.","On hardware with a dead CMOS battery, replace the battery so the clock survives reboots."],"exampleFix":"# before: clock before 1970 -> `tauri signer sign` panics\n$ date\nThu Jan  1 00:12:34 UTC 1970\n\n# after: sync and retry\n$ sudo timedatectl set-ntp true\n$ date && tauri signer sign -k ~/.tauri/myapp.key","handlingStrategy":"validation","validationCode":"// Rust: precheck before invoking signer flows\nuse std::time::{SystemTime, UNIX_EPOCH};\n\nif SystemTime::now().duration_since(UNIX_EPOCH).is_err() {\n    eprintln!(\"system clock is before the Unix epoch; enable NTP and retry\");\n    std::process::exit(1);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enable NTP/time sync on all build and signing hosts (timedatectl set-ntp true, chrony, cloud-init time services).","Add a startup sanity check (date > build epoch) in CI before signing steps.","Monitor for RTC battery failures on long-lived hardware runners."],"tags":["rust","tauri-cli","signer","updater","system-clock"],"backgroundTag":"system-clock-skew","analyzedSha":"52e4b6e71d8632a7e648f866c442e287ecddee34","analyzedAt":"2026-08-20T13:59:20.734Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}