Skip to content

{ACR} az acr check-health: fix check-health command by removing outdated API version gate for CMK check#33117

Open
lizMSFT wants to merge 1 commit intoAzure:devfrom
lizMSFT:zoeyli/acr/fix_check_health
Open

{ACR} az acr check-health: fix check-health command by removing outdated API version gate for CMK check#33117
lizMSFT wants to merge 1 commit intoAzure:devfrom
lizMSFT:zoeyli/acr/fix_check_health

Conversation

@lizMSFT
Copy link
Copy Markdown
Member

@lizMSFT lizMSFT commented Apr 1, 2026

Related command
az acr check-health

Description
PR #33017 set MGMT_CONTAINERREGISTRY's API version to None in the profile, but check_health.py still calls cmd.supported_api_version(min_api='2020-11-01-preview', resource_type=ResourceType.MGMT_CONTAINERREGISTRY) which tries to compare None against a version string, causing the 'NoneType' object has no attribute 'split' crash.

This PR removed the cmd.supported_api_version(min_api='2020-11-01-preview', ...) check — the 2020-11-01-preview feature (CMK) has been GA for years, so no need to guard it

Testing Guide
Before:

az acr check-health -n example -y
Remove Notary client version validation in next breaking change release(2.86.0) scheduled for May 2026. The Notary client version check will no longer be performed as part of the check-health command due to Docker Content Trust deprecation. To know more about the Breaking Change, please visit https://aka.ms/acr/dctdeprecation.
Docker daemon status: available
Docker version: 'Docker version 29.2.1, build 6bc6209, platform linux/amd64'
Docker pull of 'mcr.microsoft.com/mcr/hello-world:latest' : OK
Azure CLI version: 2.85.0
DNS lookup to example.azurecr.io at IP 20.62.128.0 : OK
Challenge endpoint https://example.azurecr.io/v2/ : OK
Fetch refresh token for registry 'example.azurecr.io' : OK
Fetch access token for registry 'example.azurecr.io' : OK
The command failed with an unexpected error. Here is the traceback:
'NoneType' object has no attribute 'split'
Traceback (most recent call last):
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 335, in __init__
    if 'preview' in api_version_str:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: argument of type 'NoneType' is not iterable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 375, in _parse_api_version
    return _DateAPIFormat(api_version)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 342, in __init__
    raise ValueError('The API version {} is not in a '
                     'supported format'.format(api_version_str))
ValueError: The API version None is not in a supported format

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\zoeyli\ACR\azure-cli\.venv\Lib\site-packages\knack\cli.py", line 233, in invoke
    cmd_result = self.invocation.execute(args)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\commands\__init__.py", line 677, in execute
    raise ex
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\commands\__init__.py", line 820, in _run_jobs_serially
    results.append(self._run_job(expanded_arg, cmd_copy))
                   ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\commands\__init__.py", line 789, in _run_job
    result = cmd_copy(params)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\commands\__init__.py", line 335, in __call__
    return self.handler(*args, **kwargs)
           ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\commands\command_operation.py", line 120, in handler
    return op(**command_args)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli\azure\cli\command_modules\acr\check_health.py", line 465, in acr_check_health
    _check_registry_health(cmd, registry_name, repository, ignore_errors)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli\azure\cli\command_modules\acr\check_health.py", line 352, in _check_registry_health
    if cmd.supported_api_version(min_api='2020-11-01-preview', resource_type=ResourceType.MGMT_CONTAINERREGISTRY):  # pylint: disable=too-many-nested-blocks    
       ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\commands\__init__.py", line 352, in supported_api_version
    return self.loader.supported_api_version(resource_type=resource_type, min_api=min_api, max_api=max_api,
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                             operation_group=operation_group)
                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\__init__.py", line 1401, in supported_api_version
    api_support = supported_api_version(
        cli_ctx=self.cli_ctx,
    ...<2 lines>...
        max_api=max_api,
        operation_group=operation_group)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\__init__.py", line 41, in supported_api_version
    return _sdk_supported_api_version(cli_ctx.cloud.profile,
                                      resource_type=resource_type,
                                      min_api=min_api,
                                      max_api=max_api,
                                      operation_group=operation_group)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 420, in supported_api_version
    return _validate_api_version(api_version_obj, min_api, max_api)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 397, in _validate_api_version
    if min_api and _cross_api_format_less_than(api_version_str, min_api):
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 386, in _cross_api_format_less_than
    api_version = _parse_api_version(api_version)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 377, in _parse_api_version
    return _SemVerAPIFormat(api_version)
  File "c:\users\zoeyli\acr\azure-cli\src\azure-cli-core\azure\cli\core\profiles\_shared.py", line 305, in __init__
    parts = api_version_str.split('.')
            ^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'split'
To check existing issues, please visit: https://github.com/Azure/azure-cli/issues

After:

az acr check-health -n example -y
Remove Notary client version validation in next breaking change release(2.86.0) scheduled for May 2026. The Notary client version check will no longer be performed as part of the check-health command due to Docker Content Trust deprecation. To know more about the Breaking Change, please visit https://aka.ms/acr/dctdeprecation.
Docker daemon status: available
Docker version: 'Docker version 29.2.1, build 6bc6209, platform linux/amd64'
Docker pull of 'mcr.microsoft.com/mcr/hello-world:latest' : OK
Azure CLI version: 2.85.0
DNS lookup to example.azurecr.io at IP 20.62.128.0 : OK
Challenge endpoint https://example.azurecr.io/v2/ : OK
Fetch refresh token for registry 'example.azurecr.io' : OK
Fetch access token for registry 'example.azurecr.io' : OK

History Notes


This checklist is used to make sure that common guidelines for a pull request are followed.

Copilot AI review requested due to automatic review settings April 1, 2026 16:50
@azure-client-tools-bot-prd
Copy link
Copy Markdown

Validation for Azure CLI Full Test Starting...

Thanks for your contribution!

@azure-client-tools-bot-prd
Copy link
Copy Markdown

Validation for Breaking Change Starting...

Thanks for your contribution!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes az acr check-health crashing when supported_api_version(...) attempts to compare a None API version against a version string, by removing the outdated API-version gate around the CMK (customer-managed key) identity validation.

Changes:

  • Removed cmd.supported_api_version(min_api='2020-11-01-preview', ...) gating that crashes when the profile API version is None.
  • Made CMK managed-identity validation run unconditionally (but still guarded by presence of encryption/KeyVault properties).
  • Removed now-unneeded ResourceType import.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +352 to +353
if registry and registry.encryption and registry.encryption.key_vault_properties: # pylint: disable=too-many-nested-blocks
client_id = registry.encryption.key_vault_properties.identity
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removing the API-version gate, this code path can run under profiles/SDK shapes where the registry model may not define an encryption attribute. Accessing registry.encryption directly would then raise AttributeError and reintroduce a crash in check-health. To make this robust across model versions, use attribute-safe access (e.g., getattr(registry, 'encryption', None) and similar for key_vault_properties) before dereferencing nested properties.

Suggested change
if registry and registry.encryption and registry.encryption.key_vault_properties: # pylint: disable=too-many-nested-blocks
client_id = registry.encryption.key_vault_properties.identity
encryption = getattr(registry, 'encryption', None) if registry is not None else None
key_vault_properties = getattr(encryption, 'key_vault_properties', None) if encryption is not None else None
if registry and key_vault_properties: # pylint: disable=too-many-nested-blocks
client_id = key_vault_properties.identity

Copilot uses AI. Check for mistakes.
Comment on lines +359 to +365
for k, v in registry.identity.user_assigned_identities.items():
if v.client_id == client_id:
from azure.core.exceptions import HttpResponseError
try:
valid_identity = resolve_identity_client_id(cmd.cli_ctx, k) == client_id
except HttpResponseError:
pass
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Importing HttpResponseError inside the loop is unnecessary repeated work and makes the control flow harder to read. Import it once at function scope (or at least before the loop) and keep the loop focused on the identity resolution logic.

Copilot uses AI. Check for mistakes.
@yonzhan
Copy link
Copy Markdown
Collaborator

yonzhan commented Apr 1, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

Copy link
Copy Markdown
Member

@northtyphoon northtyphoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lizMSFT lizMSFT changed the title [ACR] az acr check-health: fix check-health command by removing outdated API version gate for CMK check {ACR} az acr check-health: fix check-health command by removing outdated API version gate for CMK check Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants