embassy-rs/embassy · critical
Boot prepare error
Error message
Boot prepare error
What it means
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.
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
Example fix
// before
let loader = BootLoader::prepare(config);
// after
let loader = BootLoader::try_prepare::<ACTIVE, DFU, STATE>(config)
.unwrap_or_else(|_| BootLoader::new(config)); // or explicit fallback path Defensive patterns
Strategy: try-catch
Validate before calling
fn check_layout(active: (u32, u32), dfu: (u32, u32), state: (u32, u32)) -> bool {
[active, dfu, state].iter().all(|&(off, len)| off % 4096 == 0 && len % 4096 == 0)
} Try / catch
let loader = BootLoader::try_prepare::<ACTIVE, DFU, STATE>(config)
.unwrap_or_else(|e| { defmt::error!("boot prepare: {:?}", e); fallback_loader(config) }); Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Boot prepare error
- Boot prepare error
- unrecognized rx error
- UART DMA reported invalid `write_addr`
- Must be called from Core 0
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/db5c6e2b3b612e0a.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-boot-rp/src/lib.rs:35
use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash};
/// A bootloader for RP2040 devices.
pub struct BootLoader<const BUFFER_SIZE: usize = ERASE_SIZE> {
/// The reported state of the bootloader after preparing for boot
pub state: State,
}
impl<const BUFFER_SIZE: usize> BootLoader<BUFFER_SIZE> {
/// Inspect the bootloader state and perform actions required before booting, such as swapping firmware
pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>(
config: BootLoaderConfig<ACTIVE, DFU, STATE>,
) -> Self {
if let Ok(loader) = Self::try_prepare::<ACTIVE, DFU, STATE>(config) {
loader
} else {
// Use explicit panic instead of .expect() to ensure this gets routed via defmt/etc.
// properly
panic!("Boot prepare error")
}
}
/// Inspect the bootloader state and perform actions required before booting, such as swapping firmware
pub fn try_prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>(
config: BootLoaderConfig<ACTIVE, DFU, STATE>,
) -> Result<Self, BootError> {
let mut aligned_buf = AlignedBuffer([0; BUFFER_SIZE]);
let mut boot = embassy_boot::BootLoader::new(config);
let state = boot.prepare_boot(aligned_buf.as_mut())?;
Ok(Self { state })
}
/// Boots the application.
///
/// # Safety
///
/// This modifies the stack pointer and reset vector and will run code placed in the active partition.View on GitHub (pinned to 463a07b963)