embassy-rs/embassy · error
overflow when multiplying duration by scalar
Error message
overflow when multiplying duration by scalar
What it means
`Duration * u32` in embassy-time is implemented via `checked_mul`; if the scaled tick count overflows the duration representation, `.expect("overflow when multiplying duration by scalar")` panics. Std's `Duration` behaves the same way (documented panic on overflow).
Solutions
- Use checked arithmetic: `d.checked_mul(n).unwrap_or(Duration::MAX)`
- Cap the base duration before scaling (start backoff from a small value and cap the max delay)
- Reduce precision first (convert to seconds before multiplying) when sub-microsecond precision isn't needed
Example fix
// before let delay = base * backoff_factor; // panics when large // after let delay = base.checked_mul(backoff_factor).unwrap_or(Duration::from_secs(3600));
Defensive patterns
Strategy: validation
Validate before calling
fn safe_mul(d: embassy_time::Duration, n: u32) -> embassy_time::Duration {
d.checked_mul(n).unwrap_or(embassy_time::Duration::MAX)
} Try / catch
// Panic is not catchable in embedded; use checked mul: let scaled = d.checked_mul(n).ok_or(CalcError::Overflow)?;
Prevention
- Cap backoff/timeout base values before scaling
- Prefer checked_mul whenever the multiplier is runtime data
- Reduce precision (use seconds not micros) for large products
When it happens
Trigger: `duration * factor` where `duration` is large and `factor` pushes the product past `Duration::MAX` (e.g. `Duration::from_secs(u32::MAX) * u32::MAX` style scaling, or multiplying microsecond-precision values by big multipliers).
Common situations: Exponential backoff multipliers applied to already-large timeouts; converting units (multiplying by 1_000_000) on large second values; retry loops where the delay keeps multiplying.
Related errors
- overflow when adding durations
- overflow when subtracting durations
- divide by zero error when dividing duration by scalar
- psc division overflow
- Passphrase is too short or too long
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/efe317766bd1f3de.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-time/src/duration.rs:265
/// ## Panics
///
/// Panics if the computed duration overflows.
fn sub_assign(&mut self, rhs: Duration) {
*self = *self - rhs;
}
}
impl Mul<u32> for Duration {
type Output = Duration;
/// Computes `Duration * u32`. [Read more](Mul)
///
/// ## Panics
///
/// Panics if the computed duration overflows.
fn mul(self, rhs: u32) -> Duration {
self.checked_mul(rhs)
.expect("overflow when multiplying duration by scalar")
}
}
impl Mul<Duration> for u32 {
type Output = Duration;
/// Computes `u32 * Duration`. [Read more](Mul)
///
/// ## Panics
///
/// Panics if the computed duration overflows.
fn mul(self, rhs: Duration) -> Duration {
rhs * self
}
}
impl MulAssign<u32> for Duration {
/// Computes `Duration *= u32`. [Read more](MulAssign)View on GitHub (pinned to 463a07b963)