Repository navigation
AttributeError: module 'redis' has no attribute 'client' #34227
Description
Describe the bug
After doing:
brew uninstall --formula azure-cli
brew install azure-cliTo migrate to the Cask version of az, the following error is appearing on any az commands:
% az login
The command failed with an unexpected error. Here is the traceback:
module 'redis' has no attribute 'client'
...
AttributeError: module 'redis' has no attribute 'client'Related command
az login
Errors
% az login
The command failed with an unexpected error. Here is the traceback:
module 'redis' has no attribute 'client'
Traceback (most recent call last):
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/knack/cli.py", line 233, in invoke
cmd_result = self.invocation.execute(args)
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/commands/__init__.py", line 677, in execute
raise ex
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/commands/__init__.py", line 820, in _run_jobs_serially
results.append(self._run_job(expanded_arg, cmd_copy))
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/commands/__init__.py", line 789, in _run_job
result = cmd_copy(params)
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/commands/__init__.py", line 335, in __call__
return self.handler(*args, **kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/commands/command_operation.py", line 120, in handler
return op(**command_args)
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/command_modules/profile/custom.py", line 215, in login
subscriptions = profile.login(
interactive,
...<11 lines>...
subscription=subscription
)
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/_profile.py", line 164, in login
identity = _create_identity_instance(self.cli_ctx, self._authority, tenant_id=tenant)
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/_profile.py", line 969, in _create_identity_instance
from .auth.identity import Identity
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/auth/identity.py", line 18, in <module>
from .persistence import load_persisted_token_cache, file_extensions, load_secret_store
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/azure/cli/core/auth/persistence.py", line 12, in <module>
from msal_extensions import (FilePersistenceWithDataProtection, KeychainPersistence, LibsecretPersistence,
FilePersistence, PersistedTokenCache, CrossPlatLock)
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/msal_extensions/__init__.py", line 11, in <module>
from .token_cache import PersistedTokenCache, CrossPlatLock, LockError
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/msal_extensions/token_cache.py", line 9, in <module>
from .cache_lock import ( # pylint: disable=unused-import
...<2 lines>...
)
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/msal_extensions/cache_lock.py", line 8, in <module>
import portalocker # pylint: disable=import-error
^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/portalocker/__init__.py", line 11, in <module>
from .redis import RedisLock
File "/opt/homebrew/Caskroom/azure-cli/2.91.0/libexec/lib/python3.14/site-packages/portalocker/redis.py", line 21, in <module>
class PubSubWorkerThread(redis.client.PubSubWorkerThread):
^^^^^^^^^^^^
AttributeError: module 'redis' has no attribute 'client'Issue script & Debug output
Any az command.
Expected behavior
az cli should work, not crash
Environment Summary
azure-cli 2.91.0
core 2.91.0
telemetry 1.1.0
Extensions:
account 0.2.5
application-insights 2.0.0b2
containerapp 1.3.0b5
costmanagement 1.0.0
log-analytics 1.0.0b3
log-analytics-solution 1.0.1
logic 1.1.0
portal 1.0.0b2
quota 1.0.0
redisenterprise 1.5.0b1
storagesync 1.0.1
Dependencies:
msal 1.39.0
azure-mgmt-resource 24.0.0
Python location '/opt/homebrew/opt/python@3.14/bin/python3.14'
Config directory '/Users/thorfinn/.azure'
Extensions directory '/Users/thorfinn/.azure/cliextensions'
Python (Darwin) 3.14.8 (main, Sep 30 2026, 17:55:09) [Clang 21.0.0 (clang-2100.3.34.2)]
Legal docs and information: aka.ms/AzureCliLegal
Your CLI is up-to-date.
Additional context
No response
Activity
yonzhan commentedon Oct 15, 2026
Thank you for opening this issue, we will look into it.
thorfi commentedon Oct 15, 2026
Yong Zhang (@yonzhan) - thanks, right now I can't use the az cli at all, so this is a big problem. I tried removing my
$HOME/.azure*directories just in case, but that didn't change anything.x-engineering-agent commentedon Oct 15, 2026
@thorfi (@thorfi), the version, migration steps and traceback already identify the failure:
az logincrashes while importingmsal_extensions→portalocker→redis.client, before sign-in or token-cache access. This is the Pythonredisimport, not theazure-mgmt-redismanagement SDK. The reported invocation also goes throughbin/gitenv.sh, so we cannot yet distinguish a Cask dependency problem from that wrapper's Python import environment.Does
az loginreproduce the sameredis.clienterror when invoked directly from a fresh terminal outside the project directory, withoutbin/gitenv.sh? Please share that result, removing any tokens or personal details. That single control will determine whether to investigate the Cask's installed dependencies or the wrapper's import environment; your reply will automatically resume triage.Posted by x-engineering-agent (Fixer)
microsoft-github-policy-service commentedon Oct 15, 2026
🔔 Routing this issue to @Azure/act-identity-squad.
32 remaining items
x-engineering-agent commentedon Oct 20, 2026
Below is my analysis of this issue:
Summary
The reported
az loginfails during auth dependency imports in a project directory containing an emptyredisfolder. The reporter also observed the error in the CLI container and says Python safe-path mode avoids it. An isolated sandbox reproduced the same error on the dev build usingaz group listfrom that directory; reported/latest 2.91.0 release environments passed the same steps, so the release packaging difference is not established.🔬 Likely root cause
The launcher runs Python with
-m azure.cliwithout excluding the implicit working-directory import entry, and CLI startup imports core dependencies without removing that entry. A local emptyredisfolder can shadow the installed redis package whenportalockerimports it throughmsal_extensionsduring auth initialization; the shadow module lacksclientand stops the command before token handling. This path is reproduced on the dev sandbox, not yet established across all release launchers.Affected code
src/azure-cli/azure/cli/__main__.py›cli_main(line 26)src/azure-cli-core/azure/cli/core/_profile.py›_create_identity_instance(line 967)src/azure-cli-core/azure/cli/core/auth/persistence.py›load_persisted_token_cache(line 26)🚫 Ruled out
🛠️ Proposed change
In src/azure-cli/azure/cli/main.py, remove only the implicit unsafe CWD sys.path entry before third-party imports, compatibly with Python 3.10 and newer; audit owned -m launchers including src/azure-cli/az, az.bat, azps.ps1 and scripts/curl_install_pypi/install.py so interpreter startup cannot reintroduce it. Preserve explicit extension paths and investigate Cask packaging separately.
Workaround
The reporter says setting PYTHONSAFEPATH=1 avoids the error in their environment; leaving the directory with the shadowing redis folder also avoids it.
🔬 Technical details
Evidence
Test plan
Add a subprocess regression exercising the real auth command/import path from a directory with an empty redis folder, not just a unit test of sys.path. Cover a packaged or owned launcher and python -m entry, and confirm explicit extension imports still work. Rerun the original isolated az group list ReproSpec against the resulting PR head; check the Cask/container launchers when available.
Generated code: Handwritten code. azure/cli/main.py and azure-cli-core/auth/persistence.py are handwritten source files, not aaz or AutoRest-generated clients.
🔁 Live reproduction (BAMI sandbox) — Reproduced
Verdict: Reproduced on the current build.
Steps run (redacted)
2.91.0 (reported)
2.91.0 (latest)
dev @ ce030fb
Sandbox run
Commands ran in an isolated Azure sandbox subscription from a validated ReproSpec; output is redacted.
a0x1ab commentedon Oct 20, 2026
Apologies for the issues @thorfi (@thorfi) and Yeming Liu (@isra-fel), the X Engineering Agent faced issues as our internal testing tenant was down. This has now been fixed. Please see above for the updated bug analysis, as I have also improved the agent's capabilities. It has correctly identified and reproduced the bug as expected:
rolf-bv commentedon Oct 27, 2026
This is not only a crash. It is a security risk.
A file named redis/init.py in the current directory executes when az starts, because the launcher runs python -sm azure.cli and -m adds the current directory to sys.path before anything else.
Reproduce this by creating
redis/__init__.pywith contents:Then run
az aks listin the folder that has this newredisfolder withredis/__init__pyfile in it.No need to set the execute bit on that
__init__.pyfile, it will run fine without it and do whatever you want:A simple fix seems to be:
sudo sed -i 's/-sm/-Psm/' /usr/bin/azThis replaces
$python_cmd -smwith$python_cmd -PsmThe risk is that
azwill happily run this anywhere and its very likely not limited to theakssubcommandThis leads to unpredictable behaviour.