FuelLabs/fuel-core · error · anyhow::Error
Failed to read latest stream entry from Redis node: {e}
Error message
Failed to read latest stream entry from Redis node: {e} What it means
Same read path (crates/fuel-core/src/service/adapters/consensus_module/poa.rs:627): the Lua script completed but Redis returned a protocol-level error, carried in {e}. The cached connection is cleared before propagating; if enough other nodes answer, quorum-based reconciliation continues without the failed node.
Source
Thrown at crates/fuel-core/src/service/adapters/consensus_module/poa.rs:627
) -> anyhow::Result<Option<(u32, String)>> {
let mut connection = self.multiplexed_connection(redis_node).await?;
let latest_entry = timeout(
self.node_timeout,
redis::Script::new(READ_LATEST_STREAM_ENTRY_SCRIPT)
.key(&self.block_stream_key)
.invoke_async::<Vec<String>>(&mut connection),
)
.await;
match latest_entry {
Err(_) => {
self.clear_cached_connection(redis_node).await;
Err(anyhow!(
"Timed out reading latest stream entry from Redis node"
))
}
Ok(Err(e)) => {
self.clear_cached_connection(redis_node).await;
Err(anyhow!(
"Failed to read latest stream entry from Redis node: {e}"
))
}
Ok(Ok(entry)) => {
if entry.len() != 2 {
return Ok(None);
}
let height = entry[0]
.parse::<u32>()
.map_err(|e| anyhow!("Invalid latest stream entry height: {e}"))?;
Ok(Some((height, entry[1].clone())))
}
}
}
async fn should_reconcile_from_stream(
&self,
next_height: BlockHeight,View on GitHub (pinned to b9d4d170da)
Solutions
- Read the {e} cause: WRONGTYPE means the block:stream key is not a stream — remove or rename the foreign key after reviewing data loss
- Fix Redis health: free disk space (MISCONF), correct ACL/credentials
- Restart or replace the unhealthy node; a quorum of healthy nodes keeps the chain operating meanwhile
Example fix
# WRONGTYPE case: inspect and clear the foreign key redis-cli -u <url> TYPE <lease_key>:block:stream # -> string (bad) redis-cli -u <url> DEL <lease_key>:block:stream # stream is recreated on next publish
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight type check per node:
let key_type: String = cmd("TYPE").arg(&stream_key).query(&mut con)?;
anyhow::ensure!(key_type == "stream", "block:stream key is not a stream"); Try / catch
match read_latest(node).await {
Err(e) if e.to_string().contains("Failed to read latest stream entry") => {
// inspect root cause in {e}: WRONGTYPE/MISCONF/NOAUTH each have a distinct fix;
// exclude node this round, alert if quorum margin is gone
}
other => other,
} Prevention
- Grant the leader-lock Redis user only the permissions it needs; lock down the key prefix so foreign tools cannot overwrite it
- Alert on Redis MISCONF/OOM server-side conditions before they surface here
- Never point unrelated writers at the lease_key namespace
When it happens
Trigger: Redis errors such as WRONGTYPE ({lease_key}:block:stream holds a non-stream value), MISCONF (persistence failure, read-only state), NOAUTH/ACL denials, or an in-flight connection killed server-side.
Common situations: Another tool overwrote the stream key with a plain string; Redis hit disk-full and entered MISCONF; credentials or ACLs changed under the node; aggressive server timeout policies dropping idle connections.
Related errors
- Failed to read stream entries from Redis node: {e}
- Timed out reading latest stream entry from Redis node
- Invalid latest stream entry height: {e}
- Timed out reading stream entries from Redis node
- Backlog unresolved at height {current_height}: stream indica
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/909aa94bdb59d5b2.
Report an issue: GitHub.