embassy-rs/embassy · error
unrecognized rx error
Error message
unrecognized rx error
What it means
On RP2040/RP2350 UART, embassy-rp maps the UART's RX error interrupts (break, parity, framing) to Error variants in `read()`. If the error interrupt fired but none of `beis`, `peis`, `feis` are set, the driver cannot classify the error and panics with `unreachable!`, indicating an unhandled hardware state.
Solutions
- Update embassy-rp; newer versions may classify additional RX error sources (e.g. overrun).
- Clear pending UART error interrupts (via `uartris`/`uarticr`) before re-attempting reads.
- Check whether another task/isr shares the same UART and causes races; serialize access.
- If reproducible, capture the `uartris` register value and report it upstream as a driver bug.
Defensive patterns
Strategy: try-catch
Try / catch
// Rust panics cannot be caught on-device; handle recoverable errors via Result:
match uart.read(&mut buf) {
Ok(n) => { /* ... */ }
Err(Error::Framing) => log::warn!("framing error"),
Err(Error::Parity) => log::warn!("parity error"),
Err(e) => log::error!("uart error: {:?}", e),
} Prevention
- Clear pending error interrupts before starting reads
- Do not share the UART between tasks/ISRs without a mutex
- Use signal-quality checks (baud rate, grounding) to avoid unclassified noise errors
- Keep embassy-rp current so new RX error sources get mapped
When it happens
Trigger: A `read()` call encounters a UART error interrupt where `peris()`, `feris()`, and the break flag are all clear, so the flag chain falls through to `unreachable!`.
Common situations: Overrun conditions or noise-triggered interrupts not mapped by this driver version; concurrent access to the UART causing a stale/spurious error interrupt; hardware revisions raising additional RX error sources.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- UART DMA reported invalid `write_addr`
- Boot prepare error
- RTS and CTS pins must be either both set or none set.
- Failed to apply workaround for UART
- zero-length write.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/256791bbe43b434a.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-rp/src/uart/mod.rs:552
}
};
// If we got no error, just return at this point
if errors.0 == 0 {
return Ok(());
}
// If we DID get an error, we need to figure out which one it was.
if errors.oeris() {
return Err(Error::Overrun);
} else if errors.beris() {
return Err(Error::Break);
} else if errors.peris() {
return Err(Error::Parity);
} else if errors.feris() {
return Err(Error::Framing);
}
unreachable!("unrecognized rx error");
}
/// Read from the UART, waiting for a break.
///
/// We read until one of the following occurs:
///
/// * We read `buffer.len()` bytes without a break
/// * returns `Err(ReadToBreakError::MissingBreak(buffer.len()))`
/// * We read `n` bytes then a break occurs
/// * returns `Ok(n)`
/// * We encounter some error OTHER than a break
/// * returns `Err(ReadToBreakError::Other(error))`
///
/// **NOTE**: you MUST provide a buffer one byte larger than your largest expected
/// message to reliably detect the framing on one single call to `read_to_break()`.
///
/// * If you expect a message of 20 bytes + break, and provide a 20-byte buffer:
/// * The first call to `read_to_break()` will return `Err(ReadToBreakError::MissingBreak(20))`View on GitHub (pinned to 463a07b963)