core
core copied to clipboard
Event loop blocking call in Azure Storage
The problem
Home Assistant detected a blocking call inside the event loop when instantiating ContainerClient, in async_setup_entry and in the config flow.
What version of Home Assistant Core has the issue?
core-2025.4.2
What was the last working version of Home Assistant Core?
No response
What type of installation are you running?
Home Assistant Container
Integration causing the issue
Azure Storage
Link to integration documentation on our website
https://www.home-assistant.io/integrations/azure_storage/
Diagnostics information
No response
Example YAML snippet
Anything in the logs that might be useful for us?
2025-04-13 21:51:30.642 WARNING (MainThread) [homeassistant.util.loop] Detected blocking call to open with args ('/usr/local/bin/python3.13', 'rb') inside the event loop by integration 'azure_storage' at homeassistant/components/azure_storage/__init__.py, line 42: container_client = ContainerClient( (offender: /usr/local/lib/python3.13/platform.py, line 204: with open(executable, 'rb') as f:), please create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+azure_storage%22
For developers, please see https://developers.home-assistant.io/docs/asyncio_blocking_operations/#open
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/usr/src/homeassistant/homeassistant/__main__.py", line 227, in <module>
sys.exit(main())
File "/usr/src/homeassistant/homeassistant/__main__.py", line 213, in main
exit_code = runner.run(runtime_conf)
File "/usr/src/homeassistant/homeassistant/runner.py", line 154, in run
return loop.run_until_complete(setup_and_run_hass(runtime_config))
File "/usr/local/lib/python3.13/asyncio/base_events.py", line 712, in run_until_complete
self.run_forever()
File "/usr/local/lib/python3.13/asyncio/base_events.py", line 683, in run_forever
self._run_once()
File "/usr/local/lib/python3.13/asyncio/base_events.py", line 2040, in _run_once
handle._run()
File "/usr/local/lib/python3.13/asyncio/events.py", line 89, in _run
self._context.run(self._callback, *self._args)
File "/usr/src/homeassistant/homeassistant/setup.py", line 171, in async_setup_component
result = await _async_setup_component(hass, domain, config)
File "/usr/src/homeassistant/homeassistant/setup.py", line 467, in _async_setup_component
await asyncio.gather(
File "/usr/src/homeassistant/homeassistant/setup.py", line 469, in <genexpr>
create_eager_task(
File "/usr/src/homeassistant/homeassistant/util/async_.py", line 45, in create_eager_task
return Task(coro, loop=loop, name=name, eager_start=True)
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 896, in async_setup_locked
await self.async_setup(hass, integration=integration)
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 662, in async_setup
await self.__async_setup_with_context(hass, integration)
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 751, in __async_setup_with_context
result = await component.async_setup_entry(hass, self)
File "/usr/src/homeassistant/homeassistant/components/azure_storage/__init__.py", line 42, in async_setup_entry
container_client = ContainerClient(
Additional information
No response
Hey there @zweckj, mind taking a look at this issue as it has been labeled with an integration (azure_storage) you are listed as a code owner for? Thanks!
Code owner commands
Code owners of azure_storage can trigger bot actions by commenting:
@home-assistant closeCloses the issue.@home-assistant rename Awesome new titleRenames the issue.@home-assistant reopenReopen the issue.@home-assistant unassign azure_storageRemoves the current integration label and assignees on the issue, add the integration domain after the command.@home-assistant add-label needs-more-informationAdd a label (needs-more-information, problem in dependency, problem in custom component) to the issue.@home-assistant remove-label needs-more-informationRemove a label (needs-more-information, problem in dependency, problem in custom component) on the issue.
(message by CodeOwnersMention)
azure_storage documentation azure_storage source (message by IssueLinks)
I didn't find the actual source of the problem in the client library when browsing the code. It could be a late import, but I'm not sure.
I don't get that one, neither on my dev installation, nor my prod...
I'm getting the same warning, even after disabling the integration.
I'm definitely not a python expert (if I was, I'd try a PR here) but, taking the message at face value, it seems to be saying that you can't create a ContainerClient in the event loop, because of a call to open() somewhere down the chain (specifically platform.py), which will be out of your control. You have to create it in the executor.
I think you need to move everything from line 42 to 72 here into a method in AzureStorageBackupAgent and call it every time you need a client (having stored entry.data[CONF_ACCOUNT_NAME], entry.data[CONF_CONTAINER_NAME], entry.data[CONF_STORAGE_ACCOUNT_KEY]) in instance variables in the constructor.
This will have the added advantage of avoiding situations like someone deleting the container between startup and backup trigger.
If it's anything like the .NET client, it won't be notably slower. The create is the only thing that takes a moment and you'll only do that once either way.
No, only moving it will not help, because ultimately you'll still call it from inside the event loop. We need to find what's causing it, but it only happens together with other integrations. I was trying to analyze this with blockbuster, but I cannot reproduce this on my dev
Hmmm. I had assumed the backup controllers would be operating on an async context instead. If that's not true, can you hand client creation off to the executor with hass.async_add_executor_job(), and only create the listener when it's done?
Everything should be running inside the event loop at the moment, so there should be no difference when moving. An executor job could work, but it feels dirty to put a constructor in one.
After a quick search, I'm translating that to dotnet-speak as meaning "it's a bit dirty to mark something as bound-by-CPU when it's actually bound-by-comms but blocking". Which is a good point, though I can't say I've never done that where I couldn't have blocking code block a main thread (before almost all .NET packages removed their blocking code).
Does raise a thought in my head though: Is the reason you're not seeing this because you have another integration that's pulling in a more recent package (probably azure)? I don't know if that's even possible. But I can't think what a ContainerClient would be doing in the constructor that would require open().
I don't have that many integrations installed (I'm pretty new to HA). Certainly no others that would use Azure.
Anything I can do to help debug, do shout.
I now know where it's coming from (https://github.com/python/cpython/blob/8cf4947b0f2d37f7ffeca136ac4f99cb4cb70e5c/Lib/platform.py#L206), but I don't think I can easily get rid of that, so I'll wrap it in an executor call.