embassy-rs/embassy · error

init called more than once!

Error message

init called more than once!

What it means

Panic inside the peripheral-take helper generated by embassy's init macro: a static flag (_EMBASSY_DEVICE_PERIPHERALS) marks whether embassy::init has already handed out the Peripherals struct. A second init attempt finds the flag true and panics, because Peripherals is a singleton that grants exclusive, non-Clone ownership of all device peripherals — handing them out twice would create aliasing mutable hardware access. This is a generic one-time-initialization sentinel guard; the offending input is a second call to embassy::init (directly or via two call sites) on the same device.

Solutions

  1. Call embassy::init exactly once, early in main, and pass the resulting Peripherals down to the rest of the program
  2. Remove duplicate init calls in library/board support crates or examples copied into the project
  3. Structure the code so only main constructs Peripherals and everything else receives them as parameters
  4. If init must be re-runnable (e.g. soft reset), perform a real device reset rather than re-invoking embassy::init
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at embassy-hal-internal/src/macros.rs:67 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at embassy-hal-internal/src/macros.rs:67

        }

        impl Peripherals {
            ///Returns all the peripherals *once*
            #[inline]
            pub(crate) fn take() -> Self {
                critical_section::with(Self::take_with_cs)
            }

            ///Returns all the peripherals *once*
            #[inline]
            pub(crate) fn take_with_cs(_cs: critical_section::CriticalSection) -> Self {
                #[unsafe(no_mangle)]
                static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false;

                // safety: OK because we're inside a CS.
                unsafe {
                    if _EMBASSY_DEVICE_PERIPHERALS {
                        panic!("init called more than once!")
                    }
                    _EMBASSY_DEVICE_PERIPHERALS = true;
                    Self::steal()
                }
            }
        }

        impl Peripherals {
            /// Unsafely create an instance of this peripheral out of thin air.
            ///
            /// # Safety
            ///
            /// You must ensure that you're only using one instance of this type at a time.
            #[inline]
            pub unsafe fn steal() -> Self {
                Self {
                    $(
                        $(#[$cfg])?

View on GitHub (pinned to 463a07b963)