FuelLabs/fuel-core · error

Invalid timestamp ordering

Error message

Invalid timestamp ordering

What it means

Config::is_timestamp_accessible computes how long ago a temporal-registry key was registered by taking block.duration_since(key); Tai64N returns Err when the block timestamp is earlier than the key timestamp, which maps to 'Invalid timestamp ordering' (crates/compression/src/config.rs:30). The caller asked whether a key is accessible from a block that predates the key's registration. Invalid timestamp pairs therefore surface as this error rather than as a plain false.

Source

Thrown at crates/compression/src/config.rs:30

    /// If the value is needed again, it must be re-registered.
    pub temporal_registry_retention: Duration,
}

impl Config {
    /// Given timestamp of the current block and a key in an older block,
    /// is the key is still accessible?
    /// Returns error if the arguments are not valid block timestamps,
    /// or if the block is older than the key.
    pub fn is_timestamp_accessible(
        &self,
        block_timestamp: Tai64,
        key_timestamp: Tai64,
    ) -> anyhow::Result<bool> {
        let block = Tai64N(block_timestamp, 0);
        let key = Tai64N(key_timestamp, 0);
        let duration = block
            .duration_since(&key)
            .map_err(|_| anyhow::anyhow!("Invalid timestamp ordering"))?;
        Ok(duration <= self.temporal_registry_retention)
    }
}

View on GitHub (pinned to b9d4d170da)

Solutions

  1. Fix the inputs so block_timestamp >= key_timestamp (check argument order first).
  2. If 'block older than key' is semantically valid for your flow, treat it as not-accessible (false) instead of an error — check before calling.
  3. Add tests asserting timestamps are non-decreasing along your block pipeline.

Example fix

// before
let accessible = config.is_timestamp_accessible(block_ts, key_ts)?;

// after — treat older blocks as not accessible instead of erroring
let accessible = if block_ts < key_ts {
    false
} else {
    config.is_timestamp_accessible(block_ts, key_ts)?
};
Defensive patterns

Strategy: validation

Validate before calling

if block_timestamp < key_timestamp {
    // block predates key registration: not accessible, not an error
    return Ok(false);
}
let accessible = config.is_timestamp_accessible(block_timestamp, key_timestamp)?;

Type guard

fn is_ordering_valid(block_ts: Tai64, key_ts: Tai64) -> bool {
    block_ts >= key_ts
}

Prevention

When it happens

Trigger: Calling is_timestamp_accessible(block_timestamp, key_timestamp) with block_timestamp < key_timestamp — swapped arguments, replaying an older block, or a key whose registration timestamp is in the future relative to the block being produced.

Common situations: Swapping the two Tai64 arguments; replaying/verifying historical blocks against newer registry entries; desynced clocks when importing blocks; tests with hand-picked timestamps.

Related errors


AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16). Data as JSON: /api/errors/2b2c67d19c3ab6e8. Report an issue: GitHub.