FuelLabs/fuel-core · error
Timestamp not accessible
Error message
Timestamp not accessible
What it means
The compression crate stores repeated values (AssetId, ContractId, Address, PredicateCode, ScriptCode) in a temporal registry keyed by RegistryKey with a registration timestamp. During decompression of a value for an older block, decompress_with checks ctx.config.is_timestamp_accessible(ctx.timestamp, key_timestamp): if more time has passed since the key was registered than Config::temporal_registry_retention, the entry is considered stale and must not be used, so decompression bails. The registry is intentionally write-once/expiring; old keys are expected to be garbage-collected.
Source
Thrown at crates/compression/src/decompress.rs:181
}
macro_rules! decompress_impl {
($($type:ty),*) => { paste::paste! {
$(
impl<D> DecompressibleBy<DecompressCtx<D>> for $type
where
D: TemporalRegistry<$type>
{
async fn decompress_with(
key: RegistryKey,
ctx: &DecompressCtx<D>,
) -> anyhow::Result<Self> {
if key == RegistryKey::DEFAULT_VALUE {
return Ok(<$type>::default());
}
let key_timestamp = ctx.db.read_timestamp(&key)?;
if !ctx.config.is_timestamp_accessible(ctx.timestamp, key_timestamp)? {
anyhow::bail!("Timestamp not accessible");
}
ctx.db.read_registry(&key)
}
}
)*
}};
}
decompress_impl!(AssetId, ContractId, Address, PredicateCode, ScriptCode);
impl<D, Specification> DecompressibleBy<DecompressCtx<D>> for Coin<Specification>
where
D: DecompressDb,
Specification: CoinSpecification,
Specification::Predicate: DecompressibleBy<DecompressCtx<D>>,
Specification::PredicateData: DecompressibleBy<DecompressCtx<D>>,
Specification::PredicateGasUsed: DecompressibleBy<DecompressCtx<D>>,
Specification::Witness: DecompressibleBy<DecompressCtx<D>>,View on GitHub (pinned to b9d4d170da)
Solutions
- Only decompress blocks whose timestamp is within temporal_registry_retention of when the values were registered; obtain the data from a fresher source instead.
- Increase temporal_registry_retention in the compression Config before registering/compressing, then re-sync so entries live long enough for your historical access pattern.
- Re-register (re-compress) the value so a fresh RegistryKey/timestamp is produced, then decompress using the new key.
- Verify the block timestamps (Tai64) are sane and ordered; an inverted timestamp produces a related 'Invalid timestamp ordering' error from the same check.
Example fix
// before
let registry_retention = Duration::from_secs(60 * 60); // 1h, old blocks fail to decompress
// after
// keep registry entries valid long enough for your historical block access
let registry_retention = Duration::from_secs(60 * 60 * 24 * 30); // 30d
let config = fuel_core_compression::config::Config {
temporal_registry_retention: registry_retention,
}; Defensive patterns
Strategy: validation
Validate before calling
// Before decompressing historical data, check the value is still inside the retention window.
let age = Tai64N(block_timestamp, 0)
.duration_since(&Tai64N(key_timestamp, 0))
.ok_or_else(|| anyhow::anyhow!("key timestamp after block timestamp"))?;
if age > compression_config.temporal_registry_retention {
anyhow::bail!("registry key expired; re-register the value instead of decompressing");
}
let value = ctx.db.read_registry(&key)?; Try / catch
// Rust: treat as a non-retryable data-availability failure.
match key.decompress_with(key, &ctx).await {
Ok(v) => Ok(v),
Err(e) if e.to_string().contains("Timestamp not accessible") => {
// value expired from the temporal registry: re-register it, do not retry blindly
re_register_and_retry(key, ctx).await
}
Err(e) => Err(e),
} Prevention
- Size temporal_registry_retention to exceed the oldest block age you will ever decompress.
- Never decrease temporal_registry_retention on an existing database.
- Track registration timestamps alongside RegistryKeys so staleness is checkable before decompression.
When it happens
Trigger: Decompressing a RegistryKey whose registration timestamp is older than temporal_registry_retention relative to the block timestamp being processed (e.g., serving or replaying compressed historical blocks after a long gap, or with a short retention configured).
Common situations: temporal_registry_retention tuned down between node restarts; long node downtime followed by replay/backfill of old compressed blocks; querying historical compressed state whose registry entries have expired; clock/Tai64 timestamp anomalies making duration_since compute a too-large value.
Related errors
- Invalid timestamp ordering
- No transactions
- Last transaction is not a mint
- Compression level {value} outside of allowed range 0..=22
- Fragments use different compressions.
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/801fbe77813f6c65.
Report an issue: GitHub.