embassy-rs/embassy · critical

Boot prepare error

Error message

Boot prepare error

What it means

embassy-boot-stm32's `prepare` panics with "Boot prepare error" if `try_prepare` fails. try_prepare inspects the bootloader state and performs required pre-boot actions (firmware swap) across the ACTIVE/DFU/STATE NorFlash partitions, optionally using an aligned BUFFER. Any flash error or invalid state triggers this panic, routed via defmt instead of expect.

Solutions

  1. Use `BootLoader::try_prepare::<ACTIVE, DFU, STATE, BUFFER_SIZE>` and handle Err explicitly
  2. Verify partition offsets/sizes against the STM32 flash bank layout and linker script
  3. Ensure BUFFER_SIZE meets the required write-granularity for your STM32 family
  4. Erase or rewrite the STATE partition to a valid state on provisioning

Example fix

// before
let loader = BootLoader::prepare(config);
// after
let loader = match BootLoader::try_prepare::<ACTIVE, DFU, STATE, BUFFER_SIZE>(config) {
    Ok(l) => l,
    Err(e) => { defmt::error!("prepare failed: {:?}", e); recover(); }
};
Defensive patterns

Strategy: try-catch

Validate before calling

const BUFFER_SIZE: usize = 4096; // must be >= flash write granularity
fn partitions_ok(p: [(u32, u32); 3]) -> bool {
    p.iter().all(|&(off, len)| off % 2048 == 0 && len % 2048 == 0)
}

Try / catch

match BootLoader::try_prepare::<ACTIVE, DFU, STATE, BUFFER_SIZE>(config) {
    Ok(l) => l,
    Err(e) => { defmt::error!("prepare failed: {:?}", e); boot_recovery_image(); }
};

Prevention

When it happens

Trigger: Calling `BootLoader::prepare(BootLoaderConfig { .. })` when try_prepare returns Err: invalid/corrupted state magic in the STATE partition, NorFlash errors on any partition, or a BUFFER_SIZE too small / misconfigured partitions on STM32 internal flash.

Common situations: First boot after OTA image write with stale state; partition layout in BootLoaderConfig not matching the flash bank layout; buffer size smaller than the flash write granularity.

Related errors


AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10). Data as JSON: /api/errors/14c0df512fe15c9a. Report an issue: GitHub.

Appendix: source

Thrown at embassy-boot-stm32/src/lib.rs:29

use embedded_storage::nor_flash::NorFlash;

/// A bootloader for STM32 devices.
pub struct BootLoader {
    /// The reported state of the bootloader after preparing for boot
    pub state: State,
}

impl BootLoader {
    /// Inspect the bootloader state and perform actions required before booting, such as swapping firmware
    pub fn prepare<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash, const BUFFER_SIZE: usize>(
        config: BootLoaderConfig<ACTIVE, DFU, STATE>,
    ) -> Self {
        if let Ok(loader) = Self::try_prepare::<ACTIVE, DFU, STATE, BUFFER_SIZE>(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, const BUFFER_SIZE: usize>(
        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)