gitbutlerapp/gitbutler · error

system clock is before the Unix epoch: {err}

Error message

system clock is before the Unix epoch: {err}

What it means

Before recording the outcome of a workspace fetch, but-api stamps the attempt with SystemTime::now().duration_since(UNIX_EPOCH) in milliseconds. If the host clock reads before 1970-01-01 the duration is negative and duration_since returns Err, which this message wraps. It is purely an environment defect — a healthy machine cannot produce it — and it only affects the fetch-status bookkeeping timestamp.

Source

Thrown at crates/but-api/src/workspace.rs:127

                    .iter()
                    .find_map(|(_, err)| err.custom_context().map(|ctx| ctx.code));
                let joined = failures
                    .iter()
                    .map(|(remote, err)| format!("{remote}: {err}"))
                    .collect::<Vec<_>>()
                    .join("\n");
                let err = anyhow::anyhow!(joined);
                Err(match code {
                    Some(code) => err.context(code),
                    None => err,
                })
            }
        }
    })();

    let attempted_ms = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .map_err(|err| anyhow::anyhow!("system clock is before the Unix epoch: {err}"))?
        .as_millis()
        .try_into()
        .map_err(|err| anyhow::anyhow!("fetch timestamp does not fit in the database: {err}"))?;
    let _guard = ctx.exclusive_worktree_access();
    match &fetch_result {
        Ok(()) => ctx
            .db
            .get_cache_mut()?
            .fetch_status_mut()
            .record_success(attempted_ms)?,
        Err(err) => ctx
            .db
            .get_cache_mut()?
            .fetch_status_mut()
            .record_failure(attempted_ms, &format!("{err:#}"))?,
    }

    // A partial failure may still have updated some remote refs.

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Fix the host clock and enable NTP (e.g. timedatectl set-ntp true on Linux).
  2. Verify with `date -u` that time reads post-1970, then retry the fetch.
  3. In VMs, install guest additions/vmtools or restart the guest to resync the clock.
Defensive patterns

Strategy: try-catch

Validate before calling

if (Date.now() < 0) {
  throw new Error('system clock is set before 1970; fix host time and enable NTP');
}

Try / catch

catch (e) {
  if (String(e.message).includes('system clock is before the Unix epoch')) {
    showFatalError('Host clock invalid', 'Set the correct date, enable time synchronization, then retry.');
  }
}

Prevention

When it happens

Trigger: A workspace fetch (any API path reaching the fetch routine in crates/but-api/src/workspace.rs) on a host whose clock is set before the Unix epoch: dead RTC battery, a VM resumed with a reset clock, or a manually wrong date.

Common situations: Laptops with failed CMOS batteries; freshly cloned VMs before NTP or guest-tools sync; offline rigs with the date set wrong; CI sandboxes with mocked clocks.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/57b1b1d9411550d2. Report an issue: GitHub.