embassy-rs/embassy · error
Failed to read volume.
Error message
Failed to read volume.
What it means
UAC1 speaker volume-set handling parses the host's volume payload with `i16::from_ne_bytes(data[..2])` and expects the conversion to succeed. The host sent a SET_CUR(VOLUME) control request whose data is shorter than 2 bytes, so the slice-to-array conversion fails. This is a malformed or truncated control transfer payload.
Solutions
- Guard the length before parsing: if `data.len() < 2`, return `OutResponse::Rejected` instead of slicing
- Use `data.first_chunk::<2>()` and handle None by rejecting the request
- Check the descriptor's volume control sizes match what the host expects (b SUBFRAME / feature-unit wMaxClaimed settings) so hosts send 2-byte payloads
Example fix
// before
let volume = i16::from_ne_bytes(data[..2].try_into().expect("Failed to read volume."));
// after
let volume = match data.first_chunk::<2>() {
Some(b) => i16::from_ne_bytes(*b),
None => return OutResponse::Rejected,
}; Defensive patterns
Strategy: validation
Validate before calling
if data.len() < 2 { return OutResponse::Rejected; }
let volume = i16::from_ne_bytes(data[..2].try_into().unwrap()); Prevention
- Never slice fixed-size windows out of host-supplied control data without length checks
- Return Rejected/Stall for malformed control requests instead of panicking
- Validate that descriptor-declared control sizes match the parser's expectations
- Test with control transfer fuzzing or short-payload SET_CUR requests
When it happens
Trigger: Host issues SET_CUR on the volume control with `data.len() < 2` (empty or 1-byte wValue payload), then `interface_set_volume` panics slicing `data[..2]`.
Common situations: Non-conformant USB audio hosts/drivers sending malformed SET_CUR requests; test tools (e.g. custom control scripts) issuing volume requests with wrong wLength; OS drivers sending per-channel requests with unexpected payload framing.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- alloc_endpoint_in failed
- alloc_endpoint_out failed
- AUDIOCLK not supported yet
- cannot select OTG_HS reference clock with source frequency…
- cannot select OTG_HS reference clock with source frequency…
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/b6a19995954c2c72.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-usb/src/class/uac1/speaker.rs:521
audio_settings.muted[channel_index as usize] = mute_state;
}
_ => {
debug!("Failed to set channel {} mute state: {}", channel_index, mute_state);
return OutResponse::Rejected;
}
}
debug!("Set channel {} mute state: {}", channel_index, mute_state);
OutResponse::Accepted
}
fn interface_set_volume(
&mut self,
audio_settings: &mut AudioSettings,
channel_index: u8,
data: &[u8],
) -> OutResponse {
let volume = i16::from_ne_bytes(data[..2].try_into().expect("Failed to read volume."));
match channel_index as usize {
..=MAX_AUDIO_CHANNEL_INDEX => {
audio_settings.volume_8q8_db[channel_index as usize] = volume;
}
_ => {
debug!("Failed to set channel {} volume: {}", channel_index, volume);
return OutResponse::Rejected;
}
}
debug!("Set channel {} volume: {}", channel_index, volume);
OutResponse::Accepted
}
fn interface_set_request(&mut self, req: control::Request, data: &[u8]) -> Option<OutResponse> {
let interface_number = req.index as u8;
let entity_index = (req.index >> 8) as u8;View on GitHub (pinned to 463a07b963)