OAuth 2.0 Validation Failures During Installation
During the Nodinite installation pre-flight check, you may encounter one or both of these validation failures:
- Error [10.3] – OAuth2 client credentials validation failed
- Error [10.4] – Token claims validation failed for InstallationClient
This guide provides detailed root cause analysis, quick-reference checklists, and step-by-step solutions for all OAuth 2.0 validation scenarios.
Understanding OAuth 2.0 Validation Architecture
How Pre-Flight Validation Works
The Nodinite installation wizard performs a three-tier validation before attempting to connect to your identity provider:
present?"} C -->|No| D["Error 10.3:
Missing Config"] C -->|Yes| E["Tier 2: Client Credentials Test"] E --> F{"Token
request
succeeds?"} F -->|No| D F -->|Yes| G["Tier 3: Token Claims Validation"] G --> H{"Required
scope &
claims
present?"} H -->|No| I["Error 10.4:
Missing Claims"] H -->|Yes| J["✓ Installation Proceeds"] style D fill:#FF6B6B style I fill:#FF6B6B style J fill:#90EE90 style A fill:#87CEEB
Diagram: The pre-flight validation workflow proceeds through three tiers. Failures at any tier halt installation with specific error codes.
OAuth Configuration Components
| Component | Purpose | Configured In | Critical? |
|---|---|---|---|
| Installation Client: Client ID | Identifies the daemon application to Azure AD | OAuth2 settings → Installation Client group | ✅ Yes |
| Installation Client Secret | Proves the daemon application's identity | OAuth configuration (not shown in UI) | ✅ Yes |
| Installation Client Scopes | Requests permissions from Azure AD | OAuth2 settings → Installation Client group | ✅ Yes |
| Installation Client Claims | Specifies which token claims to validate | OAuth2 settings → Installation Client group | ✅ Yes |
| webApi Application ID | Identifies the protected API | OAuth2 settings → Installation Client group (indirectly via the scope) | ✅ Yes |
| Admin Consent Status | Grants app permissions in Azure AD | Azure AD portal | ✅ Yes |
The Installation Client fields are on the Portal's Auth step, in the Installation Client group of the OAuth2 settings section, directly below the Discovery URL. For each field's meaning and its Entra ID value, see OAuth2 settings: Discovery URL and Installation Client.
Error [10.3] – OAuth2 Client Credentials Validation Failed
What This Error Means
Error [10.3] appears when the pre-flight validation cannot obtain a valid OAuth 2.0 access token from your identity provider using the Installation Client's Client ID and secret. This is a configuration or credentials issue detected at Tier 1 or 2 of validation.
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
Work through this table to identify which root cause matches your scenario:
| # | Root Cause | How to Recognize | Evidence |
|---|---|---|---|
| 1 | Installation Client: Client ID is incorrect or missing | Copied from wrong app registration or typo | 401 Unauthorized every time |
| 2 | Installation Client Secret is incorrect, expired, or contains extra whitespace | Secret copy/paste included space, secret regenerated, secret expiry date passed | 401 Unauthorized; intermittent failures after expiry date |
| 3 | NodiniteInstallationClient app registration doesn't exist | Never registered in Azure AD, or deleted | 401 Unauthorized consistently |
| 4 | Installation Client Scopes is empty or malformed | Field left blank, or copied without .default suffix |
Different error: "Scope missing" or 400 Bad Request |
| 5 | Network/firewall blocks connection to identity provider | Outbound HTTPS to login.microsoftonline.com blocked |
Timeout errors instead of 401 |
| 6 | Identity provider down or unavailable | Azure AD 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, on the Auth step:
- Go to OAuth2 settings → Installation Client → Client ID (see Installation Client: Client ID).
- Copy the value into Notepad (to check for hidden spaces).
- Compare character-by-character with the value in Azure AD:
- Open Azure Portal > Microsoft Entra ID > App registrations.
- Search for NodiniteInstallationClient.
- Go to Overview.
- Copy the Application (client) ID.
- Match exactly – IDs are case-sensitive GUIDs.
Common mistakes:
- ❌ Copying from webClient app registration instead of NodiniteInstallationClient
- ❌ Copying from the URL (which may have partial IDs)
- ❌ Extra spaces at beginning or end
✅ Step 2: Regenerate Installation Client Secret
Installation Client Secrets cannot be viewed twice – Azure AD only displays them during creation. If you cannot find the original secret, regenerate it:
- Azure Portal > Microsoft Entra ID > App registrations > NodiniteInstallationClient.
- Go to Certificates & secrets.
- Under Client secrets, if you have an expired secret:
- Click the ⋯ (three dots) next to the expired secret.
- Select Delete.
- Click + New client secret.
- Description:
Nodinite Installation Client Secret(or your naming convention) - Expires: Choose based on your policy (e.g., 24 months)
- Click Add.
- Description:
- Copy the Value immediately (shown under Value column).
- This is the only time Azure AD displays it.
- Store securely (password manager, secure note).
- Paste this value into your Nodinite configuration (where required by your setup process).
- Ensure no extra spaces at beginning or end.
Verification:
- Open Notepad.
- Paste the secret.
- Check for leading/trailing spaces.
- If found, re-copy without spaces.
✅ Step 3: Verify Installation Client Scopes
In the Portal, on the Auth step:
- Go to OAuth2 settings → Installation Client → Installation Client Scopes (see Installation Client Scopes).
- Confirm the value is exactly:
api://<webApi-client-id>/.default - Replace
<webApi-client-id>with the Application (client) ID from your webApi app registration in Azure AD.
Example:
api://d731e991-1234-5678-90ab-cdef12345678/.default
Common mistakes:
- ❌ Missing the
.defaultsuffix (e.g.,api://d731e991-1234-5678-90ab-cdef12345678) - ❌ Including only generic scopes (e.g.,
openidorprofile) - ❌ Incomplete GUID
✅ Step 4: Verify Admin Consent Granted
In Azure AD, confirm admin consent is granted for the Installation Client:
- Azure Portal > Microsoft Entra ID > App registrations > NodiniteInstallationClient.
- Go to API permissions.
- Look for the entry
AppRole_WebApi_allfrom the webApi app. - Check the Status column:
- ✅ Should say: Granted for [Tenant Name]
- ❌ If it says: Not granted or has a warning icon
- If not granted, click Grant admin consent for [Tenant Name] and confirm.
- Only Global Administrators can do this – contact your Azure AD administrator if needed.
✅ Step 5: Verify NodiniteInstallationClient Exists
Check the app registration exists and is configured:
- Azure Portal > Microsoft Entra ID > App registrations.
- In the filter menu, ensure All applications is selected (not just "Owned by me").
- Search for NodiniteInstallationClient.
- If not found:
- Follow Register Nodinite Applications in Azure AD to create it.
- If found but missing API permissions:
- Go to API permissions.
- If
AppRole_WebApi_allis missing, add it:- Click + Add a permission.
- Select My APIs > webApi.
- Choose Application permissions (not Delegated).
- Tick
AppRole_WebApi_all. - Click Add permissions.
- Grant admin consent.
✅ Step 6: Test Network Connectivity
If Tier 1–5 pass but you still see 401 errors:
On the machine running the Nodinite installation, verify connectivity to Azure AD:
# Test HTTPS connectivity to Azure AD token endpoint
$uri = "https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token"
$result = Invoke-WebRequest -Uri $uri -Method POST -Body "grant_type=client_credentials" -ErrorAction SilentlyContinue
$result.StatusCode
# Expected: 400 Bad Request (not 401 Unauthorized or timeout)
# A successful connection returns 400 because we didn't provide credentials
If you see:
- ✅ 400 Bad Request – Network is OK, issue is credentials
- ❌ Timeout – Firewall likely blocking outbound HTTPS
- ❌ Connection refused – Firewall blocking
Error [10.4] – Token Claims Validation Failed
What This Error Means
Error [10.4] appears when the pre-flight validation obtains a valid OAuth 2.0 token successfully (Tier 2 passes) but the token lacks required claims or scopes specified in your configuration (Tier 3 fails).
This typically means:
- The token was generated successfully (credentials are correct)
- Admin consent was not granted for the required permissions in Azure AD
- The token claims are missing the required
roleorscopevalues
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 Azure AD | Missing role or scope claim in token |
| 2 | Installation Client Claims key/value incorrect | KEY field uses wrong format or VALUE doesn't match Azure AD app role | Token claims don't include required role |
| 3 | App role doesn't exist on webApi | AppRole_WebApi_all was never created on the webApi app registration |
Token doesn't include role because it wasn't exposed |
| 4 | Installation Client Scopes doesn't include .default |
Scope set to api://guid instead of api://guid/.default |
Scope not satisfied error |
Quick Fix Checklist – Error [10.4]
✅ Step 1: Verify Admin Consent for App Roles
This is the most common cause of Error [10.4]:
- Azure Portal > Microsoft Entra ID > App registrations > NodiniteInstallationClient.
- Go to API permissions.
- Find the entry AppRole_WebApi_all (from webApi app).
- Check the Status column:
- ✅ Granted for [Tenant Name] = Correct
- ⚠️ Not granted = Problem – click "Grant admin consent" and confirm
- ❌ Entry missing entirely = Add it (see Step 4 in Error [10.3] checklist)
Important:
- Admin consent appears under the permission entry, not as a button.
- If you see "Grant admin consent for [Tenant Name]" button, click it now.
- Wait 1-2 minutes for Azure AD to update tokens.
✅ Step 2: Verify Installation Client Claims Configuration
In the Portal, on the Auth step:
- Go to OAuth2 settings → Installation Client → Installation Client Claims (see Installation Client Claims).
- Verify the KEY and VALUE pair:
| Field | Correct Value |
|---|---|
| Key | http://schemas.microsoft.com/ws/2008/06/identity/claims/role |
| Value | AppRole_WebApi_all |
- Common mistakes:
- ❌ Using shortened KEY like
rolesinstead of full URL - ❌ VALUE is the description instead of the value (e.g., "Application permission for..." instead of "AppRole_WebApi_all")
- ❌ Extra spaces in either field
- ❌ Using shortened KEY like
✅ Step 3: Verify AppRole_WebApi_all Exists on webApi
Confirm the app role is created on the webApi app registration:
Azure Portal > Microsoft Entra ID > App registrations > webApi.
Go to App roles.
Look for AppRole_WebApi_all with:
- Allowed member types: Applications
- Value: AppRole_WebApi_all
- State: Enabled
If missing, create it:
- Click + Create app role.
- Display name:
AppRole_WebApi_all - Allowed member types: Applications
- Value:
AppRole_WebApi_all - Description:
Application permission for Nodinite installation and background services - State: Enabled
- Click Apply / Create.
After creating the role, return to NodiniteInstallationClient > API permissions and grant admin consent again.
✅ Step 4: Verify Installation Client Scopes (Reprise)
Even though this affects Error [10.3], it can cause Error [10.4] symptom "Scope not satisfied":
- Installation Client Scopes must end with
.default:api://<webApi-client-id>/.default - If it's missing
.default, add it now and restart installation.
Common Mistakes & How to Avoid Them
Mistake #1: Copy-Paste Includes Extra Spaces
Problem: Pasting IDs or secrets from email, chat, or browser developer tools often includes hidden spaces.
Symptoms: Error [10.3] - 401 Unauthorized every attempt
Prevention:
# Paste value into Notepad first
# Check for leading/trailing spaces
# Copy from Notepad without spaces
Mistake #2: Using webClient ID Instead of NodiniteInstallationClient ID
Problem: The Installation Client's Client ID is set to the webClient's Application (client) ID by mistake. The Web Client group has its own, separate Client ID field for that value.
Symptoms: Error [10.3] - 401 Unauthorized; webClient app permissions insufficient
Prevention:
- webClient → Used for interactive web users
- NodiniteInstallationClient → Used for automated installation (what you need here)
Mistake #3: Skipping Admin Consent
Problem: Configuration looks correct but token claims are missing.
Symptoms: Error [10.4] - Required claim missing
Prevention:
- After adding API permissions, always click Grant admin consent for [Tenant Name]
- Wait 1-2 minutes for the token claims to update in Azure AD
Mistake #4: Wrong App Role Name in Claims
Problem: Installation Client Claims VALUE field contains description instead of the actual value.
Symptoms: Error [10.4] - Required claim value not found
Example (Wrong):
KEY: http://schemas.microsoft.com/ws/2008/06/identity/claims/role
VALUE: Application permission for Nodinite installation
Example (Correct):
KEY: http://schemas.microsoft.com/ws/2008/06/identity/claims/role
VALUE: AppRole_WebApi_all
Mistake #5: Scopes Don't Match webApi Application ID
Problem: Installation Client Scopes references wrong webApi ID.
Symptoms: Error [10.4] - Required scope not satisfied
Prevention:
- Always use the Application (client) ID from webApi > Overview
- Verify it's the 36-character GUID format
- Include
.defaultsuffix
Mistake #6: Installation Client Secret Expired
Problem: Secret was created 24 months ago and has now expired.
Symptoms: Intermittent Error [10.3] - suddenly fails after passing for weeks/months
Prevention:
- Set secret expiry to match your rotation policy (e.g., 12 months)
- Calendar reminder to regenerate 30 days before expiry
- Regenerate: Azure AD > App registrations > NodiniteInstallationClient > Certificates & secrets > + New client secret
Mistake #7: Using Tenant Name Instead of Tenant ID in Discovery URL
Problem: Discovery URL includes human-friendly tenant name instead of GUID.
Symptoms: Error [10.3] - 404 Not Found or 400 Bad Request
Example (Wrong):
https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0/.well-known/openid-configuration
Example (Correct):
https://login.microsoftonline.com/a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6/v2.0/.well-known/openid-configuration
Prevention:
- Use the Directory (Tenant) ID from Azure AD > Overview (36-character GUID)
Debugging Tips
Enable Detailed Logging
If errors aren't clear, enable more verbose logging:
- Before running installation, set environment variable:
$env:NODINITE_INSTALLATION_DEBUG = $true - Run installation again.
- Check logs at:
C:\Installation\Nodinite7-DEV-Installation-Package_7.x\InstallationScripts\CommonScripts\userInputValidation-functions.ps1output - Look for HTTP status codes and response body details.
Test Token Generation Manually
Verify the Installation Client can obtain tokens:
# Install REST client if needed
Install-Module -Name RestSharp -Force
# Set variables
$tenantId = "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" # Your Directory (Tenant) ID
$clientId = "f1e2d3c4-b5a6-7890-abcd-ef1234567890" # NodiniteInstallationClient ID
$clientSecret = "your-secret-value-here"
$webApiId = "d731e991-1234-5678-90ab-cdef12345678" # webApi Application ID
# Build token request
$tokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
$body = @{
grant_type = "client_credentials"
client_id = $clientId
client_secret = $clientSecret
scope = "api://$webApiId/.default"
}
# Request token
try {
$response = Invoke-RestMethod -Uri $tokenUri -Method POST -Body $body
Write-Host "✅ Token obtained successfully!"
Write-Host "Token claims:"
$decodedToken = $response.access_token | ConvertFrom-Json
$decodedToken | ConvertTo-Json
} catch {
Write-Host "❌ Token request failed:"
Write-Host $_.Exception.Message
}
Review Azure AD Application Permissions
Sometimes permissions get removed or reset:
- Azure Portal > Microsoft Entra ID > App registrations > NodiniteInstallationClient.
- Go to API permissions.
- Verify:
- ✅
AppRole_WebApi_allis present - ✅ Status shows Granted for [Tenant Name]
- ✅ No warning icons
- ✅
- If anything is missing:
- Delete the permission (if incorrect)
- Add it again
- Grant admin consent
Check Certificate/Key Configuration
If using certificate-based authentication instead of secrets:
- Verify certificate is installed in LocalMachine > Personal on the server
- Verify certificate private key is readable by the service account
- Use PowerShell to test:
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq "your-thumbprint" }
Next Steps
Once Error [10.3] or [10.4] is resolved:
- Retry the installation wizard – Should proceed to Tier 3
- Monitor the rest of pre-flight validation – Additional checks may follow
- Verify successful connection – After installation, test Web API access with your Installation Client credentials
- Plan secret rotation – Set calendar reminder to regenerate client secret before expiry
Related Topics
- 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 OAuth 2.0 client credentials flow