embassy-rs/embassy · error
Invalid FilterConfig (TooManyFilters)! A FilterConfig must…
Error message
Invalid FilterConfig (TooManyFilters)! A FilterConfig must adhere to the constraint `2*(num_extended) + (num_standard) <= 32`.
What it means
This panic occurs when a FlexCAN `FilterConfig` is built with too many filters. The hardware has 32 filter slots, and each extended (29-bit) filter consumes two slots while each standard (11-bit) filter consumes one, so `2*(num_extended) + (num_standard) <= 32` must hold. The const constructor `__filters` converts the `TooManyFilters` validation error from `try_new` into a compile-time-evaluable panic.
Solutions
- Reduce the number of filters so `2*extended + standard <= 32`.
- Prefer standard (11-bit) filters or merge overlapping ID ranges into fewer filters (hardware filter masks can cover ranges).
- Switch to a single acceptance-mask filter covering a range instead of enumerating many exact IDs.
Example fix
// before: 17 extended filters (17*2=34 > 32) let cfg = FilterConfig::__filters(&[ext(0x18ff0100), /* ...16 more */]); // after: merge into range masks or drop to 16 extended let cfg = FilterConfig::__filters(&[ext_range(0x18ff0100, 0x18ff01ff), /* 15 more */]);
Defensive patterns
Strategy: validation
Validate before calling
// Count before constructing (non-const contexts):
fn assert_fits(filters: &[Filter]) -> bool {
let cost: usize = filters.iter().map(|f| if f.is_extended() { 2 } else { 1 }).sum();
cost <= 32
} Prevention
- Track the 32-slot budget: extended filters cost 2, standard cost 1.
- Use FilterConfig::try_new in runtime code and handle the error instead of the panicking const constructor.
- Prefer masked range filters over enumerating many exact IDs.
When it happens
Trigger: Calling `FilterConfig::__filters(...)` (or the const constructor path) with a filter list where extended filters count double plus standard filters exceeds 32, e.g. 17 extended filters (34 slots) or 20 extended + 10 standard.
Common situations: Porting a CAN config from a driver with a larger filter bank; adding filters one at a time until the total silently crosses the hardware limit; forgetting extended filters cost two slots.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid FilterConfig (EmptyFilterConfig)! A FilterConfig…
- Standard Filter Slot Too High!
- not implemented
- not implemented
- Can only take the executor once
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/e5cc888a095a91c8.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-mcxa/src/flexcan/filter.rs:116
/// Number of extended filters.
pub(crate) num_extended: usize,
}
impl<'a> FilterConfig<'a> {
/// This is an internal function that should only be
/// called via the `filters` macro.
///
/// This function calls Self::try_new(), but panics when an error is returned. This generates
/// a nice compile-time error, so long as `__filters()` is called from a `const` context. The purpose
/// of the `filters` macro is to ensure `__filters()` can only be called from a `const` context,
/// so we can do all the nice compile-time validation stuff without the possibility of a runtime panic.
#[doc(hidden)]
pub const fn __filters(filters: &'a [Filter]) -> Self {
match Self::try_new(filters) {
Ok(me) => me,
Err(FilterConfigError::TooManyFilters) => {
panic!(
"Invalid FilterConfig (TooManyFilters)! A FilterConfig must adhere to the constraint `2*(num_extended) + (num_standard) <= 32`."
);
}
Err(FilterConfigError::EmptyFilterConfig) => {
panic!("Invalid FilterConfig (EmptyFilterConfig)! A FilterConfig cannot be empty.");
}
}
}
/// Creates a new `FilterConfig` from a declarative list of filters.
///
/// The preferred way of constructing a `FilterConfig` is through the
/// `filters!()` macro (since it evaluates at compile-time), but this function
/// may be useful if you need to reconfigure filters based on runtime values.
pub const fn try_new(filters: &'a [Filter]) -> Result<Self, FilterConfigError> {
if filters.is_empty() {
return Err(FilterConfigError::EmptyFilterConfig);
}View on GitHub (pinned to 463a07b963)