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

  1. Reduce the number of filters so `2*extended + standard <= 32`.
  2. Prefer standard (11-bit) filters or merge overlapping ID ranges into fewer filters (hardware filter masks can cover ranges).
  3. 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

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


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)