FuelLabs/fuel-core · error · anyhow::Error
No P2P service available
Error message
No P2P service available
What it means
P2PAdapter holds Option<Service>; when the node runs without P2P (feature off or networking not configured) the adapter is built with service: None and every PeerToPeerPort method that needs the network errors. This one is get_sealed_block_headers: header fetches from peers are impossible. Note height_stream degrades to a pending stream, so the failure only appears once sync actually fetches.
Source
Thrown at crates/fuel-core/src/service/adapters/sync.rs:56
Some(service) => fuel_core_services::stream::IntoBoxStream::into_boxed(
tokio_stream::wrappers::BroadcastStream::new(
service.subscribe_block_height(),
)
.filter_map(|r| futures::future::ready(r.ok().map(|r| r.block_height))),
),
_ => fuel_core_services::stream::IntoBoxStream::into_boxed(
tokio_stream::pending(),
),
}
}
async fn get_sealed_block_headers(
&self,
block_height_range: Range<u32>,
) -> anyhow::Result<SourcePeer<Option<Vec<SealedBlockHeader>>>> {
let result = match &self.service {
Some(service) => service.get_sealed_block_headers(block_height_range).await,
_ => Err(anyhow::anyhow!("No P2P service available")),
};
match result {
Ok((peer_id, headers)) => {
let peer_id: PeerId = peer_id.into();
let headers = peer_id.bind(headers);
Ok(headers)
}
Err(err) => Err(err),
}
}
async fn get_transactions(
&self,
block_ids: Range<u32>,
) -> anyhow::Result<SourcePeer<Option<Vec<Transactions>>>> {
let result = match &self.service {
Some(service) => service.get_transactions(block_ids).await,
_ => Err(anyhow::anyhow!("No P2P service available")),View on GitHub (pinned to b9d4d170da)
Solutions
- Enable P2P: build with `--features p2p` and provide network configuration (bootstrap nodes, etc.).
- If networking is intentionally off, use snapshot/import-based sync instead of peer sync.
- Fix configs that both disable p2p and enable peer-driven sync.
Defensive patterns
Strategy: type-guard
Validate before calling
// Before relying on peer sync, confirm P2P is configured:
fn p2p_available(config: &Config) -> bool {
#[cfg(feature = "p2p")]
{ config.p2p.is_some() }
#[cfg(not(feature = "p2p"))]
{ false }
}
if !p2p_available(&config) {
anyhow::bail!("peer header fetch unavailable: P2P not configured");
} Type guard
fn is_peer_sync_capable(config: &Config) -> bool {
cfg!(feature = "p2p") && config.p2p.is_some()
} Try / catch
match header_fetch {
Err(e) if e.to_string().contains("No P2P service available") => {
// expected on non-networked nodes: fall back to snapshot/import sync
tracing::warn!("P2P unavailable; skipping peer header fetch");
return Ok(None);
}
other => other,
} Prevention
- Decide the sync mode upfront: peer sync requires p2p config + feature; otherwise use snapshot/import.
- Fail config validation when sync-from-peers is requested but p2p is None.
- Remember height_stream silently pends without P2P — absence of heights is the early symptom.
When it happens
Trigger: The sync service calls get_sealed_block_headers(block_height_range) on a node whose P2PAdapter has no service — p2p disabled in config or the binary built without the p2p feature.
Common situations: Local/dev nodes started without network config but attempting state sync; binaries without the p2p feature pointed at a chain that requires peer sync; config where p2p is None while sync is active.
Related errors
- Compression level {value} outside of allowed range 0..=22
- Failed to create FuelClient. No URL is provided.
- {error}
- Relayer is too far out of sync
- Timed out while connecting to redis leader-lock node
AI-assisted analysis of FuelLabs/fuel-core@b9d4d170da (2026-08-16).
Data as JSON: /api/errors/058edd64b1250cb4.
Report an issue: GitHub.