{"record":{"id":"fbdb55ea1b90ceaf","repo":"FuelLabs/fuel-core","slug":"cannot-have-a-da-height-above-zero-without-a-relay","errorCode":null,"errorMessage":"Cannot have a da height above zero without a relayer","messagePattern":"Cannot have a da height above zero without a relayer","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/fuel-core/src/service/adapters/consensus_module.rs","lineNumber":82,"sourceCode":"        &self,\n        da_height: &DaBlockHeight,\n        _max_da_lag: &DaBlockHeight,\n    ) -> anyhow::Result<()> {\n        #[cfg(feature = \"relayer\")]\n        {\n            if let Some(sync) = &self.relayer_synced {\n                let current_height = sync.get_finalized_da_height();\n                anyhow::ensure!(\n                    da_height.saturating_sub(*current_height) <= **_max_da_lag,\n                    \"Relayer is too far out of sync\"\n                );\n                sync.await_at_least_synced(da_height).await?;\n            }\n            Ok(())\n        }\n        #[cfg(not(feature = \"relayer\"))]\n        {\n            anyhow::ensure!(\n                **da_height == 0,\n                \"Cannot have a da height above zero without a relayer\"\n            );\n            Ok(())\n        }\n    }\n}\n","sourceCodeStart":64,"sourceCodeEnd":90,"githubUrl":"https://github.com/FuelLabs/fuel-core/blob/b9d4d170da3a31c9ace5f963d633b326348e0d42/crates/fuel-core/src/service/adapters/consensus_module.rs#L64-L90","documentation":"Same RelayerPort adapter but the not(relayer) branch (crates/fuel-core/src/service/adapters/consensus_module.rs:82). The binary was compiled without the relayer feature, so there is no DA synchronization source at all; the adapter therefore rejects any block whose header da_height is above zero, since it could never verify DA finality for it.","triggerScenarios":"Running a fuel-core build without the relayer feature (MaybeRelayerAdapter has no relayer_synced path) while producing or importing a block whose da_height > 0.","commonSituations":"Local/dev builds with default features receiving blocks from a DA-connected network; a buggy or malicious producer setting a non-zero da_height; embedding fuel-core as a library without enabling optional relayer features.","solutions":["Build and run the node with the relayer feature enabled (cargo build --features relayer or the full preset binary)","If DA is genuinely unused in this deployment, fix producers so blocks are created with da_height = 0","Reject the offending block at the p2p/import boundary instead of letting it reach consensus"],"exampleFix":"# before: cargo build -p fuel-core --no-default-features\n# after:  cargo build -p fuel-core --features relayer\n// (or, where DA is unused, produce blocks with header da_height == 0)","handlingStrategy":"validation","validationCode":"// library users building blocks without the relayer feature:\nfn valid_da_height(cfg: &ProducerConfig, da_height: DaBlockHeight) -> bool {\n    #[cfg(not(feature = \"relayer\"))]\n    { da_height == DaBlockHeight(0) }\n    #[cfg(feature = \"relayer\")]\n    { true }\n}","typeGuard":"fn build_has_relayer() -> bool {\n    cfg!(feature = \"relayer\")\n}","tryCatchPattern":"if let Err(e) = port.await_until_if_in_range(&da_height, &lag).await {\n    if e.to_string().contains(\"without a relayer\") {\n        // build/feature mismatch or bad producer: fail loudly, retrying cannot help\n    }\n}","preventionTips":["If your network has any DA connectivity, always build/deploy the relayer-enabled binary","In DA-less deployments, assert producers emit da_height == 0","Document feature choice next to the deployment config so ops knows which binary flavor runs"],"tags":["fuel-core","relayer","feature-flags","da-height","build-config"],"backgroundTag":null,"analyzedSha":"b9d4d170da3a31c9ace5f963d633b326348e0d42","analyzedAt":"2026-08-16T08:56:42.692Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}