embassy-rs/embassy · error
The read size for the concatenated flashes must be the same
Error message
The read size for the concatenated flashes must be the same
What it means
When concatenating two flashes with `ConcatFlash::new`, embassy-embedded-hal computes the combined READ_SIZE at compile time via the const fn `get_read_size`. If the two flashes declare different READ_SIZE constants, the panics fire because a single read granularity cannot represent both. This is a const-eval panic, so it usually fails during compilation of the const initializer.
Solutions
- Use flashes with identical READ_SIZE values, or wrap one flash in an adapter that normalizes its READ_SIZE
- Check each flash's READ_SIZE associated constant in its NorFlash impl
- Insert the two flashes in a different order/type so both share a read size
- Implement a small wrapper flash type overriding READ_SIZE to the common value if reads are effectively byte-granular
Example fix
// before let flash = ConcatFlash::new(spi_flash /* READ_SIZE=4 */, internal_flash /* READ_SIZE=1 */); // after let flash = ConcatFlash::new(spi_flash, WrappedFlash::<_, 4>::new(internal_flash)); // aligned READ_SIZE=4
Defensive patterns
Strategy: validation
Validate before calling
const fn read_sizes_match<A: NorFlash, B: NorFlash>() -> bool { A::READ_SIZE == B::READ_SIZE }
const _: () = assert!(read_sizes_match::<MyFlashA, MyFlashB>(), "READ_SIZE mismatch for ConcatFlash"); Prevention
- Check READ_SIZE of both flashes before combining with ConcatFlash
- Wrap mismatched flashes in an adapter normalizing READ_SIZE
- Add a const assert for flash constants in your board support crate
- Re-verify flash constants after driver version bumps
When it happens
Trigger: `ConcatFlash::new(flash_a, flash_b)` (or the type alias/const initializer feeding ReadNorFlash/AsyncReadNorFlash impls) where `First::READ_SIZE != Second::READ_SIZE`.
Common situations: Concatenating different flash chips (e.g. a 1-byte-read internal flash with a 4-byte-read SPI flash); upgrading a driver whose READ_SIZE constant changed; copy-pasting ConcatFlash config across boards with different second flash.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- The write size for the concatenated flashes must be the same
- The erase sizes for the concatenated flashes must have have…
- Partition offset must be a multiple of read, write and…
- Partition size must be a multiple of read, write and erase…
- Partition offset must be a multiple of read, write and…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/d7a67c81443d557a.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-embedded-hal/src/flash/concat_flash.rs:20
use embedded_storage_async::nor_flash::{
MultiwriteNorFlash as AsyncMultiwriteNorFlash, NorFlash as AsyncNorFlash, ReadNorFlash as AsyncReadNorFlash,
};
/// Convenience helper for concatenating two consecutive flashes into one.
/// This is especially useful if used with "flash regions", where one may
/// want to concatenate multiple regions into one larger region.
pub struct ConcatFlash<First, Second>(First, Second);
impl<First, Second> ConcatFlash<First, Second> {
/// Create a new flash that concatenates two consecutive flashes.
pub fn new(first: First, second: Second) -> Self {
Self(first, second)
}
}
const fn get_read_size(first_read_size: usize, second_read_size: usize) -> usize {
if first_read_size != second_read_size {
panic!("The read size for the concatenated flashes must be the same");
}
first_read_size
}
const fn get_write_size(first_write_size: usize, second_write_size: usize) -> usize {
if first_write_size != second_write_size {
panic!("The write size for the concatenated flashes must be the same");
}
first_write_size
}
const fn get_max_erase_size(first_erase_size: usize, second_erase_size: usize) -> usize {
let max_erase_size = if first_erase_size > second_erase_size {
first_erase_size
} else {
second_erase_size
};
if max_erase_size % first_erase_size != 0 || max_erase_size % second_erase_size != 0 {View on GitHub (pinned to 463a07b963)