Problem
Just an idea - cosmos/azure is very complex and problems tend to jump out of the box from nowehere. Would maybe be helpful to let the shell check problems for you before they occur.
After GA, the most common support traffic for a CLI is usually not feature requests — it is "it does not connect", "I get 403", or "it hangs". Diagnosing those today requires a round trip to collect shell version, install method, platform, auth mode, connection mode, endpoint, and RBAC state.
There is no single command that collects this and renders a verdict. info reports resource configuration and usage, and connect reports the current connection, but neither answers what is broken and what to do about it.
Proposed solution
Add a read-only doctor command that runs a fixed set of checks and reports PASS / WARN / FAIL / SKIP with actionable remediation text.
doctor
doctor --database MyDb --container Items
doctor --format json
Example output:
PASS Shell version 1.0.213-preview (dotnet tool)
PASS Authentication Azure CLI credential acquired
PASS Account endpoint Reachable in 84 ms (Direct)
WARN Control plane No ARM context (account-key auth)
mkdb/mkcon/rmdb/rmcon/indexpolicy may fail under strict data-plane RBAC.
Reconnect with Entra ID, or pass --subscription and --resource-group.
FAIL Container access 403 Forbidden
Required data-plane role: Cosmos DB Built-in Data Reader
Scope: three tiers
ARM is not required, and must stay optional.
| Tier |
Requires |
Checks |
| 0 |
nothing |
shell version, OS/arch, install method, .NET runtime, relevant env vars, DNS, proxy, TLS, clock skew |
| 1 |
data plane |
credential acquisition, endpoint reachability, connection mode, database/container existence, read + query permission |
| 2 |
ARM (opt-in) |
account resource resolution, control-plane reachability, role assignments |
Tier 2 runs only when an ARM context already exists on the state, or when the user passes --arm explicitly. A missing ARM context is reported as SKIP, never FAIL.
Why ARM must stay optional
CosmosArmResourceProvider.TryCreateContextAsync returns null immediately when credential == null, so account-key and connection-string auth have no ARM context at all.
- The emulator has no ARM.
CosmosArmResourceProvider.DiscoverContextAsync enumerates every subscription and every Cosmos account until the endpoint matches. That is far too slow to sit on a diagnostic command's default path.
- CI and workload-identity principals frequently have no ARM permission by design.
Notable checks
- ARM-context gap (highest value). The comment above
CosmosArmResourceProvider.TryCreateContextAsync already documents this: key auth means no ARM context, so control-plane commands (mkdb, mkcon, rmdb, rmcon, indexpolicy) fall back to the data plane and then fail on accounts with strict data-plane RBAC. doctor should name this explicitly instead of leaving users to discover it through a failed command.
- RBAC parsing reuse.
InfoCommand.PrincipalIdRegex already parses does not have required RBAC permissions to perform action. Extract and reuse it rather than writing a second parser.
- Direct-mode port probe. Direct mode needs outbound TCP 10250-10256. On corporate networks this presents as a hang rather than an error; the check should recommend
--connect-mode gateway.
- Clock skew. Drift beyond roughly 5 minutes breaks token validation with unhelpful errors.
- Emulator certificate. Certificate validation is bypassed only for emulator endpoints, so a self-signed certificate on a non-emulator endpoint should be flagged rather than silently failing.
Non-goals for v1
- No
--fix and no mutating behavior. doctor stays read-only so it is safe to run and safe to paste into an issue.
- No duplication of
info or connect output beyond what a verdict requires.
Acceptance criteria
Problem
Just an idea - cosmos/azure is very complex and problems tend to jump out of the box from nowehere. Would maybe be helpful to let the shell check problems for you before they occur.
After GA, the most common support traffic for a CLI is usually not feature requests — it is "it does not connect", "I get 403", or "it hangs". Diagnosing those today requires a round trip to collect shell version, install method, platform, auth mode, connection mode, endpoint, and RBAC state.
There is no single command that collects this and renders a verdict.
inforeports resource configuration and usage, andconnectreports the current connection, but neither answers what is broken and what to do about it.Proposed solution
Add a read-only
doctorcommand that runs a fixed set of checks and reportsPASS/WARN/FAIL/SKIPwith actionable remediation text.Example output:
Scope: three tiers
ARM is not required, and must stay optional.
Tier 2 runs only when an ARM context already exists on the state, or when the user passes
--armexplicitly. A missing ARM context is reported asSKIP, neverFAIL.Why ARM must stay optional
CosmosArmResourceProvider.TryCreateContextAsyncreturnsnullimmediately whencredential == null, so account-key and connection-string auth have no ARM context at all.CosmosArmResourceProvider.DiscoverContextAsyncenumerates every subscription and every Cosmos account until the endpoint matches. That is far too slow to sit on a diagnostic command's default path.Notable checks
CosmosArmResourceProvider.TryCreateContextAsyncalready documents this: key auth means no ARM context, so control-plane commands (mkdb,mkcon,rmdb,rmcon,indexpolicy) fall back to the data plane and then fail on accounts with strict data-plane RBAC.doctorshould name this explicitly instead of leaving users to discover it through a failed command.InfoCommand.PrincipalIdRegexalready parsesdoes not have required RBAC permissions to perform action. Extract and reuse it rather than writing a second parser.--connect-mode gateway.Non-goals for v1
--fixand no mutating behavior.doctorstays read-only so it is safe to run and safe to paste into an issue.infoorconnectoutput beyond what a verdict requires.Acceptance criteria
doctorruns with no connection and still produces Tier 0 results--armopts in--database/--containertarget explicitly, consistent with other commands--format jsonoutputlang/en.ftldocs/commands.mdplus a troubleshooting section