rustfs/rustfs · error · HeartbeatError

the stored Connect device certificate is not currently valid

Error message

the stored Connect device certificate is not currently valid

What it means

The stored Connect device certificate's validity window does not cover the current time. Before every heartbeat POST, TelemetryTransport::authenticated_client checks `now < credential.not_before_unix || now >= credential.not_after_unix` (rustfs/src/connect/telemetry.rs:131-134) and this variant (converted from TelemetryError::CredentialExpired at heartbeat.rs:432) is returned when the check fails. The runtime refuses to send telemetry with a credential the control plane would reject anyway.

Source

Thrown at rustfs/src/connect/heartbeat.rs:377

}

#[derive(Debug, thiserror::Error)]
pub enum HeartbeatError {
    #[error("Connect heartbeat endpoint must be an HTTPS base URL without credentials, query, or fragment")]
    Endpoint,
    #[error("Connect heartbeat root CA configuration is invalid")]
    RootCertificate,
    #[error("Connect heartbeat schedule is invalid")]
    Schedule,
    #[error("RustFS is not registered with Connect")]
    NotRegistered,
    #[error("the Connect device private key is missing")]
    IdentityMissing,
    #[error("the stored Connect certificate and device private key cannot form a TLS identity")]
    IdentityCertificate,
    #[error("the stored Connect credential name is invalid")]
    CredentialName,
    #[error("the stored Connect device certificate is not currently valid")]
    CredentialExpired,
    #[error("the Connect heartbeat node summary is outside protocol bounds")]
    NodeSummary,
    #[error("the Connect heartbeat sequence is exhausted")]
    SequenceExhausted,
    #[error("a Connect heartbeat runtime already owns this state")]
    AlreadyRunning,
    #[error("the persisted Connect heartbeat changed while delivery was in flight")]
    StateConflict,
    #[error("Connect heartbeat state I/O failed at {path}: {source}")]
    StateIo {
        path: PathBuf,
        #[source]
        source: io::Error,
    },
    #[error("Connect heartbeat state at {path} is invalid: {source}")]
    StateInvalid {
        path: PathBuf,

View on GitHub (pinned to 201c653dcd)

Solutions

  1. Check and correct the system clock (NTP/chrony/systemd-timesyncd), then restart -- clock skew is the most common cause
  2. If the clock is correct, the certificate is genuinely outside its window: re-register this RustFS deployment with Connect using a fresh registration token to obtain a new device credential
  3. Inspect the stored credential's notBefore/notAfter timestamps to confirm which side of the window `now` falls on
Defensive patterns

Strategy: try-catch

Type guard

fn is_credential_expired(err: &HeartbeatError) -> bool {
    matches!(err, HeartbeatError::CredentialExpired)
}

Try / catch

match sender.send(&pending).await {
    Ok(delivery) => { /* handle delivery */ }
    Err(HeartbeatError::CredentialExpired) => {
        // Not retryable as-is: fix the clock or re-register with Connect.
        alert("Connect device certificate outside its validity window");
        runtime.stop().await;
    }
    Err(e) => { tracing::warn!(error = %e, "heartbeat failed"); }
}

Prevention

When it happens

Trigger: Calling heartbeat send paths when the system clock is earlier than the certificate's notBefore, at/past its notAfter, or skewed far enough to fall outside the window; restoring an old credential store; a certificate issued against a since-corrected clock.

Common situations: NTP drift or a stopped clock in VMs/containers; a VM resumed from snapshot with stale time; the device certificate simply aged past expiry because re-registration never happened.

Understand the failure class

Related errors


AI-assisted analysis of rustfs/rustfs@201c653dcd (2026-08-23). Data as JSON: /api/errors/3b02f124d6262b9e. Report an issue: GitHub.