embassy-rs/embassy · error

invalid max_packet_size_0, the allowed values are 8, 16, 32…

Error message

invalid max_packet_size_0, the allowed values are 8, 16, 32 or 64

What it means

Builder::new validates that UsbConfig::max_packet_size_0 is one of the USB-legal control endpoint sizes 8, 16, 32, or 64 and panics otherwise. EP0's max packet size goes straight into the device descriptor bMaxPacketSize0, which only permits these values.

Solutions

  1. Set max_packet_size_0: 64 (standard for full/high-speed devices).
  2. Restrict the value to 8/16/32/64 before constructing the Builder.
  3. Define the control EP size as a const so it is validated at compile time.

Example fix

// before
let config = Config { max_packet_size_0: ep_size, .. }; // ep_size = 512
// after
let config = Config { max_packet_size_0: 64, .. };
Defensive patterns

Strategy: validation

Validate before calling

fn valid_max_packet_size_0(n: u16) -> bool { matches!(n, 8 | 16 | 32 | 64) }
assert!(valid_max_packet_size_0(config.max_packet_size_0));

Type guard

fn valid_max_packet_size_0(n: u16) -> bool { matches!(n, 8 | 16 | 32 | 64) }

Prevention

When it happens

Trigger: Constructing a UsbDevice with max_packet_size_0 set to any value other than 8/16/32/64 (0, 128, 512, or a bulk-endpoint size).

Common situations: Reusing an endpoint's max_packet_size for EP0; computing sizes for high-speed and copying them into EP0; default-then-overwrite patterns that leave an invalid value.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at embassy-usb/src/builder.rs:209

        control_buf: &'d mut [u8],
    ) -> Self {
        // Magic values specified in USB-IF ECN on IADs.
        if config.composite_with_iads
            && (config.device_class != 0xEF || config.device_sub_class != 0x02 || config.device_protocol != 0x01)
        {
            panic!(
                "if composite_with_iads is set, you must set device_class = 0xEF, device_sub_class = 0x02, device_protocol = 0x01"
            );
        }

        assert!(
            config.max_power <= 500,
            "The maximum allowed value for `max_power` is 500mA"
        );

        match config.max_packet_size_0 {
            8 | 16 | 32 | 64 => {}
            _ => panic!("invalid max_packet_size_0, the allowed values are 8, 16, 32 or 64"),
        }

        let mut config_descriptor = DescriptorWriter::new(config_descriptor_buf);
        let mut bos_descriptor = BosWriter::new(DescriptorWriter::new(bos_descriptor_buf));

        config_descriptor.configuration(&config);
        bos_descriptor.bos();

        Builder {
            driver,
            config,
            interfaces: Vec::new(),
            handlers: Vec::new(),
            control_buf,
            next_string_index: STRING_INDEX_CUSTOM_START,

            config_descriptor,
            bos_descriptor,

View on GitHub (pinned to 463a07b963)