{"record":{"id":"db5c6e2b3b612e0a","repo":"embassy-rs/embassy","slug":"boot-prepare-error-db5c6e","errorCode":null,"errorMessage":"Boot prepare error","messagePattern":"Boot prepare error","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"embassy-boot-rp/src/lib.rs","lineNumber":35,"sourceCode":"use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};\n\n/// A bootloader for RP2040 devices.\npub struct BootLoader<const BUFFER_SIZE: usize = ERASE_SIZE> {\n    /// The reported state of the bootloader after preparing for boot\n    pub state: State,\n}\n\nimpl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> {\n    /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware\n    pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>(\n        config: BootLoaderConfig<ACTIVE, DFU, STATE>,\n    ) -> Self {\n        if let Ok(loader) = Self::try_prepare::<ACTIVE, DFU, STATE>(config) {\n            loader\n        } else {\n            // Use explicit panic instead of .expect() to ensure this gets routed via defmt/etc.\n            // properly\n            panic!(\"Boot prepare error\")\n        }\n    }\n\n    /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware\n    pub fn try_prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>(\n        config: BootLoaderConfig<ACTIVE, DFU, STATE>,\n    ) -> Result<Self, BootError> {\n        let mut aligned_buf = AlignedBuffer([0; BUFFER_SIZE]);\n        let mut boot = embassy_boot::BootLoader::new(config);\n        let state = boot.prepare_boot(aligned_buf.as_mut())?;\n        Ok(Self { state })\n    }\n\n    /// Boots the application.\n    ///\n    /// # Safety\n    ///\n    /// This modifies the stack pointer and reset vector and will run code placed in the active partition.","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-boot-rp/src/lib.rs#L17-L53","documentation":"embassy-boot-rp's `prepare` panics with \"Boot prepare error\" when the internal `try_prepare` fails. try_prepare inspects bootloader state and performs pre-boot actions (firmware swap) on the RP2040/RP2350 active, DFU and state flash partitions; any NorFlash error or invalid state causes the panic. It is deliberately a panic rather than expect so the message goes through defmt.","triggerScenarios":"Calling `BootLoader::prepare(BootLoaderConfig { .. })` when try_prepare returns Err: corrupted or uninitialized STATE partition, flash read/write/erase failure on ACTIVE/DFU/STATE, or partition config inconsistent with the actual flash layout.","commonSituations":"Fresh device with unformatted DFU/state sectors; wrong flash offsets in BootLoaderConfig after linker script changes; flash chip driver returning errors on the RP2040 XIP/UART flash path.","solutions":["Use `BootLoader::try_prepare` and handle the Result yourself","Confirm BOOTLOADER/ACTIVE/DFU/STATE partition offsets and sizes match your linker script","Initialize the state partition (erase or write valid magic) before first boot","Log the underlying error from try_prepare to find which flash operation failed"],"exampleFix":"// before\nlet loader = BootLoader::prepare(config);\n// after\nlet loader = BootLoader::try_prepare::<ACTIVE, DFU, STATE>(config)\n    .unwrap_or_else(|_| BootLoader::new(config)); // or explicit fallback path","handlingStrategy":"try-catch","validationCode":"fn check_layout(active: (u32, u32), dfu: (u32, u32), state: (u32, u32)) -> bool {\n    [active, dfu, state].iter().all(|&(off, len)| off % 4096 == 0 && len % 4096 == 0)\n}","typeGuard":null,"tryCatchPattern":"let loader = BootLoader::try_prepare::<ACTIVE, DFU, STATE>(config)\n    .unwrap_or_else(|e| { defmt::error!(\"boot prepare: {:?}\", e); fallback_loader(config) });","preventionTips":["Handle try_prepare's Result explicitly rather than using prepare","Confirm partition offsets/sizes against the RP2040/RP2350 flash map","Initialize state partition magic before the first OTA-capable boot","Test a fresh-flash first boot in CI hardware runs"],"tags":["embedded","bootloader","firmware-update","panic","rp2040"],"backgroundTag":"boot-prepare-error","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}