embassy-rs/embassy · error
Partition offset must be a multiple of read, write and…
Error message
Partition offset must be a multiple of read, write and erase size
What it means
`BlockingPartition::new` is the blocking (RefCell-based) counterpart of the async Partition and performs the identical const-time validation: the offset must be a multiple of the flash's READ_SIZE, WRITE_SIZE and ERASE_SIZE, otherwise it panics. Because the constructor is const, the panic occurs during const evaluation of the partition definition.
Solutions
- Align the offset to T::ERASE_SIZE (the dominant constraint) before constructing the partition
- Define offsets as multiples of the flash's erase sector size in a shared layout module
- Verify with a const assertion that offset % T::ERASE_SIZE == 0 in your layout code
- Recompute all partition offsets after any change of underlying flash hardware
Example fix
// before let part = BlockingPartition::new(&flash, 512, 4096); // 512 not multiple of ERASE_SIZE 4096 // after let part = BlockingPartition::new(&flash, 4096, 4096); // aligned
Defensive patterns
Strategy: validation
Validate before calling
const fn blocking_offset_ok<T: NorFlash>(offset: u32) -> bool {
offset % T::READ_SIZE as u32 == 0
&& offset % T::WRITE_SIZE as u32 == 0
&& offset % T::ERASE_SIZE as u32 == 0
} Prevention
- Align offsets to the flash's ERASE_SIZE before constructing BlockingPartition
- Reuse the same layout constants between async and blocking partitions
- Add const assertions in the settings/storage module for offset alignment
- Audit offsets after any change of backing flash hardware or sector size
When it happens
Trigger: Calling `BlockingPartition::new(&mutex_flash, offset, size)` where `offset % T::READ_SIZE != 0 || offset % T::WRITE_SIZE != 0 || offset % T::ERASE_SIZE != 0` — e.g. offset 0x100 on a flash with WRITE_SIZE 8 and ERASE_SIZE 4096 that isn't a 4096 multiple.
Common situations: Settings/OTA storage partitions placed at arbitrary byte offsets; layouts copied from a datasheet's byte map that ignores sector granularity; changing the backing flash to one with larger erase sectors without moving partitions.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Partition offset must be a multiple of read, write and…
- Partition size must be a multiple of read, write and erase…
- The erase sizes for the concatenated flashes must have have…
- The read size for the concatenated flashes must be the same
- The write size for the concatenated flashes must be the same
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/ce8cd1db1e332253.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-embedded-hal/src/flash/partition/blocking.rs:37
size: u32,
}
impl<'a, M: RawMutex, T: NorFlash> Clone for BlockingPartition<'a, M, T> {
fn clone(&self) -> Self {
Self {
flash: self.flash,
offset: self.offset,
size: self.size,
}
}
}
impl<'a, M: RawMutex, T: NorFlash> BlockingPartition<'a, M, T> {
/// Create a new partition
pub const fn new(flash: &'a Mutex<M, RefCell<T>>, offset: u32, size: u32) -> Self {
if offset % T::READ_SIZE as u32 != 0 || offset % T::WRITE_SIZE as u32 != 0 || offset % T::ERASE_SIZE as u32 != 0
{
panic!("Partition offset must be a multiple of read, write and erase size");
}
if size % T::READ_SIZE as u32 != 0 || size % T::WRITE_SIZE as u32 != 0 || size % T::ERASE_SIZE as u32 != 0 {
panic!("Partition size must be a multiple of read, write and erase size");
}
Self { flash, offset, size }
}
/// Get the partition offset within the flash
pub const fn offset(&self) -> u32 {
self.offset
}
/// Get the partition size
pub const fn size(&self) -> u32 {
self.size
}
}
View on GitHub (pinned to 463a07b963)