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

  1. Use `BootLoader::try_prepare` and handle the Result yourself
  2. Confirm BOOTLOADER/ACTIVE/DFU/STATE partition offsets and sizes match your linker script
  3. Initialize the state partition (erase or write valid magic) before first boot
  4. 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

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


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)