bleak icon indicating copy to clipboard operation
bleak copied to clipboard

Windows: Enabling indications fails with Protocol Error 0x03 (Write Not Permitted)

Open es617 opened this issue 6 months ago • 3 comments

Hi there, thanks for the great library and continued support! I’m using bleak version 1.0.1 with Python 3.11.9 to build a CLI tool that interacts with a custom BLE device. The device exposes multiple characteristics that support reading, writing, notifications, and indications.

On macOS and Ubuntu, everything works as expected — including enabling indications.

However, on Windows (running in a Parallels VM with BLE passthrough from the macOS host, MacBook Air M4), I consistently get this error when attempting to enable indications on one of the characteristics:

Could not start notify on 0030: Protocol Error 0x03: Write Not Permitted

Notifications (also via start_notify) do work on Windows.

async def notify_characteristic(self, uuid, state=True):
    if not self.client or not self.client.is_connected:
        logger.info("[red]Not connected to any device.[/red]")
        return None
    try:
        specifier = self.parse_char_specifier(uuid)
        if state:
            await self.client.start_notify(specifier, self.default_notify_callback)
            logger.info(f"[green]Started notification for {uuid}.[/green]")
        else:
            await self.client.stop_notify(specifier)
            logger.info(f"[green]Stopped notification for {uuid}.[/green]")
    except Exception as e:
        action = "starting" if state else "stopping"
        logger.info(
            f"[red]Error {action} notification for characteristic:[/red] {e}"
        )
        return {"error": str(e)}

Additional context • The UUID is correct. • All the characteristics are unencrypted, so there is no pairing or bonding involved. • The characteristic has the Indicate property. • Notifications work fine for other characteristics on Windows. • This works flawlessly on macOS and Ubuntu. • Environment: Windows 11 (Parallels VM on macOS), BLE shared via passthrough • Python version: 3.11.9

I also enabled Bleak debug logging, and I see logs for most operations — connection, discovery, reads, writes, etc. — but no logs are printed around the time the Protocol Error 0x03 occurs during start_notify for indications.

Questions • Is this a known Windows-specific limitation when enabling indications? • Could it be related to BLE passthrough from macOS via Parallels? • Any known workarounds or debugging steps you recommend?

Thanks in advance!

es617 avatar Jul 10 '25 22:07 es617

Is this a known Windows-specific limitation when enabling indications?

Don't know. I've only used notifications, not indications.

Could it be related to BLE passthrough from macOS via Parallels?

Maybe. Not sure how they handle this. As a workaround, you could use a USB Bluetooth dongle so that Windows gets it's very own Bluetooth adapter (assuming Parallels handles USB devices like other VM's I've used where the VM gets full control of the USB device).

Any known workarounds or debugging steps you recommend?

Logging Bluetooth packets is always the number one way to understand issues like this. https://bleak.readthedocs.io/en/latest/troubleshooting.html#capture-bluetooth-traffic

Could not start notify on 0030: Protocol Error 0x03: Write Not Permitted

What is the full stack trace?

The characteristic has the Indicate property.

It might not hurt to log the value of cccd that is used when calling write_client_characteristic_configuration_descriptor_with_result_async() to make sure our logic is correct in picking notify or indicate.

dlech avatar Jul 10 '25 23:07 dlech

Thanks for the prompt response, @dlech.

It's doesn't seem a bleak issue. I see the same behavior using the Bluetooth LE Explorer app. I wanted to double-check using nRF Connect, but it doesn't find the passthrough BLE from macOS at all.

I'll test with a real Windows machine asap to see if that's the problem.

Regarding your other points:

  1. Full Trace:
Traceback (most recent call last):
  File "C:\Users\enrico\ug-ble-cli\uroguard\ble_controller.py", line 274, in notify_characteristic
    await self.client.start_notify(specifier, self.default_notify_callback)
  File "C:\Users\enrico\bleak\bleak\__init__.py", line 785, in start_notify
    await self._backend.start_notify(
  File "C:\Users\enrico\bleak\bleak\backends\winrt\client.py", line 998, in start_notify
    _ensure_success(
  File "C:\Users\enrico\bleak\bleak\backends\winrt\client.py", line 137, in _ensure_success
    raise BleakError(
bleak.exc.BleakError: Could not start notify on 0030: Protocol Error 0x03: Write Not Permitted
  1. Added some debug prints in start_notify for WinRT:
start_notify called for characteristic handle: 48
winrt_char.characteristic_properties: 32
Using INDICATE for CCCD (cccd=2)
Adding value changed handler
Writing CCCD value 2 to characteristic 48
Exception in start_notify: Could not start notify on 0030: Protocol Error 0x03: Write Not Permitted (cccd=2)

For notifications:

start_notify called for characteristic handle: 39
winrt_char.characteristic_properties: 18
Using NOTIFY for CCCD (cccd=1)
Adding value changed handler
Writing CCCD value 1 to characteristic 39
Successfully started notify on 39 (cccd=1)
  1. I have an external BLE dongle, but it's not working at all with passthrough. I can only use the macOS native hardware.

  2. Before I get into sniffing traffic, I'll try to test in a real windows machine to reduce the scope.

Anything else I could try?

Finally, I noticed another interesting issue for another characteristic that supports write. max_write_without_response_size returned 244 on Windows, but the writes failed until I lowered the packet size to 182 (which is what I usually get on macOS). So I suspect somehow the passthrough is causing issues with MTU sizes as well.

es617 avatar Jul 11 '25 17:07 es617

Anything else I could try?

Your current plan sounds optimal.

So I suspect somehow the passthrough is causing issues with MTU sizes as well.

Indeed!

dlech avatar Jul 11 '25 18:07 dlech