OAuth 2.0 Validation Failures During Installation
When a Nodinite v7 Environment uses OAuth2 mode, the installer CLI (Nodinite.Installer.Cli.exe, see Step 7) checks the identity provider values before it changes the server. It runs this pre-flight check in validate, and before every install or update. You may see one or both of these failures:
- Error [10.3] – OAuth2 client credentials validation failed
- Error [10.4] – Token claims validation failed for InstallationClient
Both concern the NodiniteInstallationClient, the daemon identity the CLI uses to work against the Web API without user interaction. This guide explains the checks, then gives root causes and fixes for each error.
Understanding OAuth 2.0 Validation Architecture
How Pre-Flight Validation Works
and Claims set?"} Config -->|"No"| E104a["Error 10.4
scope or claim not satisfied"] Config -->|"Yes"| Secret{"Installation client
secret supplied?"} Secret -->|"No"| Skip["Warning 10.3
live token test skipped"] Secret -->|"Yes"| Token{"Client credentials
token request succeeds?"} Token -->|"No"| E103["Error 10.3
client credentials failed"] Token -->|"Yes"| Claims{"Token carries the
required role claim?"} Claims -->|"No"| E104b["Error 10.4
claim missing"] Claims -->|"Yes"| Ok["Installation proceeds"] Skip --> Ok style Start fill:#2678BD style E104a fill:#c33d34 style E103 fill:#c33d34 style E104b fill:#c33d34 style Skip fill:#FFD525 style Ok fill:#93d16d
Red nodes stop the installation, the yellow warning means the live test didn't run, so a consent or secret problem can still surface later, and green means the pre-flight check passed. The checked values are the Installation Client Scopes and Installation Client Claims from the Portal Step 2: Auth, and the client secret you pass to the CLI.
OAuth Configuration Components
| Component | Purpose | Configured In | Critical? |
|---|---|---|---|
| Installation Client: Client ID | Identifies the daemon application to Entra ID | Portal OAuth2 settings → Installation Client | ✅ Yes |
| Installation client secret | Proves the daemon application's identity | Not stored in the Portal: CLI prompt or --oauth2-agentinstall-secret, see Client Secrets |
✅ Yes |
| Installation Client Scopes | Requests the webApi application permissions | Portal OAuth2 settings → Installation Client | ✅ Yes |
| Installation Client Claims | The token claims the check requires | Portal OAuth2 settings → Installation Client | ✅ Yes |
| webApi Application ID | Identifies the protected API | Indirectly, through the scope | ✅ Yes |
| Admin consent | Grants the application permission | Entra ID admin center | ✅ Yes |
For each field's meaning and its Entra ID value, see OAuth2 settings: Discovery URL and Installation Client and the OpenID Field Mapping Quick Reference.
Error [10.3] – OAuth2 Client Credentials Validation Failed
What This Error Means
The pre-flight check couldn't obtain an access token from your identity provider with the Installation Client's Client ID and secret. This is a credentials, registration, or connectivity issue.
Common Error Messages
ERROR: [10.3] OAuth2 client credentials validation failed for InstallationClient.
Response status code does not indicate success: 401 (Unauthorized).
ERROR: [10.3] OAuth2 client credentials validation failed for InstallationClient.
One or more errors occurred: 'InvalidClientSecret' or 'Unknown_UserType'
Root Cause Analysis
| # | Root Cause | How to Recognize | Evidence |
|---|---|---|---|
| 1 | Installation Client: Client ID is incorrect or missing | Copied from the wrong app registration, or a typo | 401 Unauthorized every time |
| 2 | Client secret is incorrect, expired, or contains extra whitespace | Copy/paste added a space, the secret was regenerated, or it expired | 401 Unauthorized; a sudden failure after weeks of success |
| 3 | NodiniteInstallationClient app registration doesn't exist | Never registered, or deleted | 401 Unauthorized consistently |
| 4 | Installation Client Scopes is malformed | Copied without the .default suffix |
400 Bad Request, "scope" in the message |
| 5 | Discovery URL uses the tenant name or a wrong tenant ID | Discovery URL doesn't hold the Directory (tenant) ID GUID | 400 or 404 |
| 6 | Firewall or proxy blocks the identity provider | Outbound HTTPS to login.microsoftonline.com blocked |
Timeout instead of 401 |
| 7 | Identity provider unavailable | Entra ID service issue (rare) | Timeout or 5xx server error |
Quick Fix Checklist – Error [10.3]
Follow these steps in order. Most cases are resolved by steps 1–3.
Step 1: Verify the Installation Client: Client ID
- In the Portal Auth step, open OAuth2 settings → Installation Client → Client ID (see Installation Client: Client ID).
- Copy the value into a plain text editor to reveal hidden spaces.
- Compare it with Microsoft Entra ID > App registrations > NodiniteInstallationClient > Overview > Application (client) ID.
Typical mistakes are the webClient ID instead of the NodiniteInstallationClient ID, a partial ID copied from a URL, and leading or trailing spaces.
Step 2: Regenerate the Client Secret
Entra ID shows a client secret only once, when you create it. If you don't have it, or it expired:
- Microsoft Entra ID > App registrations > NodiniteInstallationClient > Certificates & secrets.
- Delete the expired secret under Client secrets (⋯ > Delete).
- Click + New client secret, enter a description such as
Nodinite Installation Client Secretand an expiry that matches your rotation policy, and click Add. - Copy the Value immediately and store it in your secret vault.
- Pass it to the CLI at the prompt or with
--oauth2-agentinstall-secret, without leading or trailing spaces; see Step 7: Passing arguments.
Step 3: Verify Installation Client Scopes
- Open OAuth2 settings → Installation Client → Installation Client Scopes (see Installation Client Scopes).
- Confirm the value is exactly
api://<webApi-client-id>/.default, with the Application (client) ID of the webApi app registration, for exampleapi://d731e991-1234-5678-90ab-cdef12345678/.default.
Typical mistakes are a missing .default suffix, only generic scopes such as openid, and an incomplete GUID.
Step 4: Verify Admin Consent Granted
- Microsoft Entra ID > App registrations > NodiniteInstallationClient > API permissions.
- Find
AppRole_WebApi_allfrom the webApi app and check the Status column:- ✅ Granted for [Tenant Name]: correct.
- ❌ Not granted, or a warning icon: click Grant admin consent for [Tenant Name] and confirm.
Granting tenant-wide admin consent needs an administrator role that is allowed to grant it, such as Global Administrator or Privileged Role Administrator; ask your Entra ID administrator if the button is unavailable.
Step 5: Verify NodiniteInstallationClient Exists
- Microsoft Entra ID > App registrations, with the filter set to All applications (not just "Owned by me").
- Search for NodiniteInstallationClient. If it doesn't exist, create it with Register Nodinite Applications in Azure AD.
- If
AppRole_WebApi_allis missing under API permissions, add it: + Add a permission > My APIs > webApi > Application permissions, tickAppRole_WebApi_all, click Add permissions, and grant admin consent.
Step 6: Test Connectivity to the Identity Provider
On the server where you run the CLI, fetch the discovery document from the Discovery URL:
# Expect StatusCode 200 and the token_endpoint of your tenant
$r = Invoke-WebRequest -Uri "https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration"
$r.StatusCode
($r.Content | ConvertFrom-Json).token_endpoint
| Result | Meaning |
|---|---|
| ✅ 200 with your token endpoint | Network and tenant ID are OK; the issue is the credentials |
| ❌ 400 or 404 | Wrong tenant ID or tenant name in the Discovery URL |
| ❌ Timeout or connection refused | Firewall or proxy blocks outbound HTTPS; see the Network and Firewall Overview and Configure Network / Proxy |
Error [10.4] – Token Claims Validation Failed
What This Error Means
The Installation Client Scopes or Installation Client Claims are missing or wrong, or the token the CLI obtained lacks the required scope or role claim. When the credentials work but the claim is missing, admin consent was usually not granted.
Common Error Messages
ERROR: [10.4] Token claims validation failed for InstallationClient.
Required scope 'api://<webApi-client-id>/.default' not satisfied
ERROR: [10.4] Token claims validation failed for InstallationClient.
Required claim 'http://schemas.microsoft.com/ws/2008/06/identity/claims/role' is missing
ERROR: [10.4] Token claims validation failed for InstallationClient.
Required claim value 'AppRole_WebApi_all' not found in token
Root Cause Analysis – Error [10.4]
| # | Root Cause | How to Recognize | Evidence |
|---|---|---|---|
| 1 | Admin consent not granted for AppRole_WebApi_all | Status shows "Not granted" in Entra ID | The role claim is missing from the token |
| 2 | Installation Client Claims key/value incorrect | Shortened KEY, or the description instead of the value | Required claim value not found |
| 3 | App role doesn't exist on webApi | AppRole_WebApi_all was never created |
The token can't carry the role |
| 4 | Installation Client Scopes lacks .default |
api://guid instead of api://guid/.default |
Scope not satisfied |
| 5 | webApi issues version 1 tokens | requestedAccessTokenVersion isn't 2 |
Claim format differs |
Quick Fix Checklist – Error [10.4]
Entra ID Token Claims Validation walks through these fixes in detail, including the access token version.
Step 1: Verify Admin Consent for App Roles
This is the most common cause. Check the Status of AppRole_WebApi_all as in Step 4 of the Error [10.3] checklist, grant consent if needed, and wait 1–2 minutes before you rerun the CLI.
Step 2: Verify Installation Client Claims Configuration
Open OAuth2 settings → Installation Client → Installation Client Claims (see Installation Client Claims) and verify the pair:
| Field | Correct Value |
|---|---|
| Key | http://schemas.microsoft.com/ws/2008/06/identity/claims/role |
| Value | AppRole_WebApi_all |
Typical mistakes are a shortened KEY such as roles, the role's description as VALUE (for example "Application permission for…"), and extra spaces.
Step 3: Verify AppRole_WebApi_all Exists on webApi
- Microsoft Entra ID > App registrations > webApi > App roles.
- Look for AppRole_WebApi_all with Allowed member types Applications, Value
AppRole_WebApi_all, and State Enabled. - If it's missing, create it as in Register Nodinite Applications in Azure AD, section 1.3.1, then grant admin consent again on NodiniteInstallationClient > API permissions.
Step 4: Verify Installation Client Scopes
The scope must end with .default (api://<webApi-client-id>/.default); see Step 3 of the Error [10.3] checklist.
Common Mistakes and How to Avoid Them
| Mistake | Symptom | Prevention |
|---|---|---|
| Copy-paste adds hidden spaces to an ID or secret | Error [10.3], 401 on every attempt | Paste into a plain text editor first and trim |
| webClient ID used as the Installation Client's Client ID | Error [10.3], 401 | webClient is for interactive users; the Installation Client needs the NodiniteInstallationClient ID |
| Admin consent skipped | Error [10.4], required claim missing | Always click Grant admin consent after adding API permissions, then wait 1–2 minutes |
| Role description used as Claims VALUE | Error [10.4], claim value not found | Use the role Value: AppRole_WebApi_all |
| Scope references the wrong webApi ID | Error [10.4], scope not satisfied | Use the webApi Application (client) ID from its Overview, with .default |
| Client secret expired | Error [10.3] after weeks or months of success | Set a calendar reminder 30 days before expiry, create a new secret, and rerun the update |
| Tenant name instead of tenant ID in the Discovery URL | Error [10.3], 400 or 404 | Use the Directory (tenant) ID GUID: https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration |
Debugging Tips
Get Detailed CLI Output
Run the pre-flight check on its own and write a JSON report you can share with support:
.\Nodinite.Installer.Cli.exe validate --config .\localhost\config.cli.json --output report.json --format json
deploy-environment --verbose gives the same detail during an install or update; see Step 7: Troubleshooting.
Test Token Generation Manually
Request a token for the Installation Client and decode its claims:
$tenantId = "<tenant-id>" # Directory (tenant) ID
$clientId = "<installation-client-id>" # NodiniteInstallationClient
$clientSecret = Read-Host "Client secret" -MaskInput
$webApiId = "<webApi-client-id>" # webApi Application (client) ID
$body = @{
grant_type = "client_credentials"
client_id = $clientId
client_secret = $clientSecret
scope = "api://$webApiId/.default"
}
$token = (Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Body $body).access_token
# Decode the JWT payload (base64url) to inspect aud, ver, and roles
$payload = $token.Split('.')[1].Replace('-', '+').Replace('_', '/')
$payload = $payload.PadRight($payload.Length + (4 - $payload.Length % 4) % 4, '=')
$claims = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($payload)) | ConvertFrom-Json
$claims | Select-Object aud, ver, roles
| Result | Meaning |
|---|---|
✅ roles holds AppRole_WebApi_all, ver is 2.0 |
Entra ID is correct; check the Portal values |
| ❌ The request fails with 401 | Error [10.3] causes: client ID or secret |
❌ roles is empty |
Error [10.4] causes: admin consent or app role |
⚠️ ver is 1.0 |
Set requestedAccessTokenVersion to 2 on webApi (section 1.6) |
Check Certificate Credentials
If your organization uses a certificate credential for the NodiniteInstallationClient instead of a client secret, verify under Certificates & secrets that it hasn't expired, and that the certificate with its private key is in the LocalMachine certificate store of the server that runs the CLI.
After the Fix
- Rerun
validate, then the install or update; see Step 7. - Watch the rest of the pre-flight check; other checks may follow.
- Verify access to the Web API after installation; see Call the Web API with OAuth 2.0 Client Credentials.
- Plan secret rotation before the new secret expires.
Next Steps
Related Topics
- OAuth 2.0 Troubleshooting
- Install Nodinite v7 – OpenID Connect
- Register Nodinite Applications in Azure AD (Entra ID) with OpenID Connect
- OAuth Security and Compliance Reference
- Managing the Web API – code samples for the OAuth 2.0 client credentials flow