Where to start
Find the area where the problem appears, then match the symptom.
- Client reporting: collection, upload and the report table.
- Central management: deployment: the API and portal do not start or sign-in fails.
- Central management: devices and requests: devices do not register or answer.
- Central management: license:
HW-LIC-*codes. - App Control management: inventory, the Board, rules and packages.
Logs: the client writes %ProgramData%\Highwind\cache\service.log. The Fleet Agent writes to the Windows Application event log. The API writes every security decision to its audit log, visible in the portal under Activity.
Client reporting
| Symptom | Cause and fix |
|---|---|
No latest.json in the cache folder | Collection is off or has not run. Set EnableBackgroundCollector = 1, confirm the Collect task exists with Get-ScheduledTask -TaskName "Highwind*", or run Highwind.exe --collect --no-upload as an administrator. |
| Upload log shows Silent sign-in unavailable | The device is not Entra joined to the tenant that owns the Function App, so there is no primary refresh token. Run Highwind.exe --auth-login once as the user. See Verification. |
Upload returns 401 | FunctionAppAudience does not match the Application ID URI of the Function App registration, or the identity provider on the Function App points to another app. |
Upload returns 403 | Conditional Access blocked the token (for example, the device is not compliant), or the Function App restricts callers by IP address or private endpoint. |
| Upload succeeds but no row appears | The Function App's managed identity lacks Storage Table Data Contributor, or its storage settings name another account or table. Check the function's invocation log. |
| Power BI shows no data or an authentication error | The query points at another storage account or table, or the account used in Power BI has no read access to Table Storage. In Azure Government, use the Government version of the query. |
Central management: deployment
Problems deploying or starting the Management API and Portal, and signing in to them.
| Symptom | Cause and fix |
|---|---|
Device certificate mode: HW-AUTH-001 on attest | The API refused the proof and wrote the reason to its audit log (DeviceAttestationRejected). Usual causes: attestation not allowed for the tenant (portal → Device identity), the join type not allowed, the device disabled or deleted in Entra, or the API lacking Graph Device.Read.All (step 7b) |
Device certificate mode: HW-IDENT-001 | Device identity is off on the API, or it cannot use the Key Vault key. Check the Fleet__DeviceIdentity__* settings (7c) and the Crypto User role on the key (7a); Create and test now in the portal confirms the fix |
Device certificate mode: HW-IDENT-003, device disabled | The same Entra device presented more than three new keys in a day, which looks like a copied identity. Investigate, then return it to service in the portal |
403, or needs the … permission in the portal | The signed-in person’s Access assignment does not include that permission, or the device is outside its tags. Access changes apply within 30 seconds |
| Deployment fails with site failed to start within 10 mins; docker log shows exit code 134 | The API crashed at startup. Read LogFiles/StartupLogs/*_failure.log in Kudu for the Unhandled exception. A SQL error occurred during the login process there means the database was unavailable (resuming or failing over); 3.7.0 now retries schema and tenant seeding for Fleet__Database__SchemaInitializationTimeoutSeconds (60 s) before giving up. BadImageFormatException or Culture is not supported from the running site during a deployment means files were replaced under it: set WEBSITE_RUN_FROM_PACKAGE=1 so a zip deploy swaps atomically |
401 with a real token | The token’s issuer or audience is not accepted. Decode it (the verification script prints both) and compare with ValidIssuers / ValidAudiences. The usual cause is leaving ValidIssuers empty while Entra issues v1 tokens (https://sts.windows.net/{tenant-id}/); see step 5 |
Failed to add identifier URI ... must contain a tenant verified domain, tenant ID, or app ID | Your tenant's default identifier-URI policy. Use api://{app-id} (as step 1 does) or api://{verified-domain}/highwind-fleet, and use that same value for the API Audience, the portal scope, the script's -Audience and FleetManagementAudience. |
sqlcmd: Failed to authenticate the user '' ... ActiveDirectoryIntegrated ... Could not discover a user realm | The legacy ODBC sqlcmd ran, not the Go edition. Install it with winget install sqlcmd, then Set-Alias sqlcmd "$env:ProgramFiles\SqlCmd\sqlcmd.exe" (in the setup block) and confirm with sqlcmd --version. To make it permanent, add the alias to your $PROFILE. In Azure Government, also run az cloud set --name AzureUSGovernment and az login first. |
AADSTS65001 from az account get-access-token | The Azure CLI is not an authorized client of the API. Add 04b07795-8ddb-461a-bbee-02f9e1bf7b46 under Expose an API → Add a client application |
/health/ready fails with a valid token, or startup logs Login failed for user '<token-identified principal>' | The web app’s managed identity has no database user (step 4), or the SQL firewall / private endpoint blocks App Service (step 2d) |
Portal deploy waits 10 minutes, then Site failed to start; /health/live returns 503 | The portal stops at startup when a setting is missing. Its log shows OptionsValidationException ... The ApiBaseAddress field is required. Run step 6c, then confirm with az webapp config appsettings list -g $rg -n $portalApp --query "[].name" -o tsv. Saving the settings restarts the site, so you do not need to redeploy. Read the log with az webapp log download -g $rg -n $portalApp --log-file portal-logs.zip |
| Portal shows Not permitted for a user who holds a Highwind role | Roles are assigned on the API registration (step 1c) and reach the portal through the API’s access token. Check the assignment under Enterprise applications → Highwind Fleet Management → Users and groups, then sign out and back in, because the portal reads roles once at sign-in |
Startup logs Invalid object name | The schema was not applied (step 3). The service never creates it itself |
| Portal exits: “ApiBaseAddress field is required” | Portal__* settings are missing from the portal web app |
| Portal redirect URI mismatch in Azure | Set Portal__BehindReverseProxy = true |
Central management: devices and requests
Problems with devices registering, authenticating or answering questions.
| Symptom | Cause and fix |
|---|---|
| Device never appears; the agent log says Could not acquire a token for the management service | Entra ID mode only. On an Entra joined or hybrid joined device, switch to Device certificate mode instead. Otherwise: the service has no identity (see Turn on endpoints, step 2), the certificate path or app ID in its Environment value is wrong, or, in Azure Government, AzureEnvironment is not USGOV. Check with (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\HighwindFleetAgent).Environment |
Device certificate mode: the audit log shows DeviceAttestationRejected with not Entra joined, or nothing happens | The agent found no MS-Organization-Access certificate. Run dsregcmd /status: it needs AzureAdJoined : YES. Hybrid join can take a sync cycle after the domain join. Registered (Workplace) devices are not supported |
Device certificate mode: DeviceAttested, then AgentRegistrationDenied with HW-DOMAIN-001 | The tenant enforces a domain allowlist and the device reported no domain (an Entra joined device has none). API 3.7.0 builds from 1 October 2026 accept an attested device that reports no domain; update the API. A device that reports a domain (hybrid joined) must still be in AuthorizedDomains; add it with the SQL in step 5 |
Every call returns 403 | App-role values are wrong. They must be exactly Highwind.Agent, Highwind.Operator, Highwind.Admin (not Highwind.Fleet.*). Decode the token and check the roles claim |
400 HW-REQUEST-006 | The body has a member the contract does not define; usually tenantId or agentId in an operator request, query or poll |
404 for a device you can see elsewhere | Your token is for another tenant. Cross-tenant access is deliberately indistinguishable from “does not exist” |
409 on heartbeat | Sequence number did not increase (replay protection) |
A question to a device returns HW-CAP-001 | The device cannot answer that operation. For a custom query: the device has not turned custom queries on; set FleetCustomChecksEnabled = 1 (REG_DWORD) under HKLM\SOFTWARE\Policies\Highwind (ADMX Allow administrator-defined custom checks) and Restart-Service HighwindFleetAgent. For any other operation: the agent is older than 3.7.0; install the current MSI |
| A question stays Pending, then Expired | The device did not check in within 5 minutes: it is offline, the service is stopped, or FleetBrokeredMessagingEnabled (Allow the agent to receive requests) is off. Check Get-Service HighwindFleetAgent on the device and ask again |
403 submitting a request | The device did not advertise that operation in its capabilities |
400 HW-AI-002 on an egress grant | bundleHash must be a base64 SHA-256 (44 characters), not hex; justification must be 16–1024 characters |
403 HW-AI-001 on an egress grant | The tenant has AllowModelEgress = false |
| Agent logs “must use HTTPS” / stops at startup | An invalid Fleet policy value. The event log names it. See the value ranges |
| Posture shows No posture reported yet for an active device | The device reports at its next check-ins after approval (two check-ins for all 7 answers). If it stays empty: the device did not advertise the posture questions (agent older than 3.7.0), Allow the agent to receive requests is off, or Fleet__Management__PostureRefreshIntervalMinutes is 0 and nobody selected a refresh |
Central management: license
License codes returned by the portal and API. Devices are never affected by the license state.
| Symptom | Cause and fix |
|---|---|
403 HW-LIC-MISSING-001 on every page | No license is imported (common right after upgrading). An administrator opens Admin → License and imports the .hwlic file. Devices keep reporting meanwhile |
403 HW-LIC-EXPIRED-001 when changing anything | The license has expired; the portal is read-only. Import the renewal |
403 HW-LIC-FEATURE-001, or a menu item is missing | The license does not include that feature (see the Features table on Admin → License) |
403 HW-LIC-LIMIT-001 approving a device | The license’s device limit is reached. Disable or revoke devices you no longer manage, or ask for a higher limit |
Import refused: HW-LIC-SIGNATURE-001 / HW-LIC-KEY-001 | The file was changed or was not signed by Highwind (or needs a newer release that knows its key). Ask Highwind for the original file; do not edit it |
Import refused: HW-LIC-BINDING-001 | The license is bound to another tenant or installation. Send Highwind the Installation ID from Admin → License |
App Control management
Problems with App Control inventory, the Application Control Board, rules and packages.
| Symptom | Cause and fix |
|---|---|
| App Control is not in the navigation | The module is off. Admin → App Control management: Visibility Only and Policy inventory, then reload |
| App Control shows every device as not reported | Posture has not collected GetWdacStatus in the last 24 hours, or the worker has not run yet. Full posture sync (all devices) on Posture, wait one poll interval plus a minute |
403 HW-APPCTL-001 | The module is off for the tenant (reads), or a mode or capability not built in this release was requested (settings), or an import was sent with Advanced hunting off, or a rule route was called without mode Recommend, Governance and Rule recommendations (impact routes also need Policy simulation). Use Visibility Only, Governance or Recommend with the capabilities this release offers |
Approve missing, or 409 “Simulate the rule’s impact first” | Policy simulation is on and the rule has no simulation from the last MaxAgeHours (72). Open Impact on the proposal and simulate |
Scan files missing, or 409 “No active device … offers file scans” | Set FleetAppControlFileScanEnabled = 1 on devices that have the application, run the 3.7.0 agent, Restart-Service HighwindFleetAgent; tick Application file scans |
| A scan says Not found | The device has no install record for the application with a usable folder, or the folder is refused (drive root, Windows, Program Files root, profile root). The reason is shown. MSI applications that record no install folder (most MSI packages) are found through Windows Installer by agents built from 4 October 2026: update the agent and scan again |
| Package is a Draft: the issuing certificate’s TBS hash or the Authenticode hash is not on record | The evidence came from Advanced Hunting imports or an older agent. Scan the application’s files (section 9) or wait for new Code Integrity events from a 3.7.0 agent, then build again |
| “TBS hash for Unknown (Unknown) is not on record” on a rule signed by Unknown | The file is unsigned and a device reported the signer as Unknown. Builds from 5 October 2026 treat such values as unsigned (file-attribute or hash rule). Reopen the review, Generate candidates again, propose and approve the new rule, then build the package again |
409 “There is nothing to build a rule from yet” | No App Control events and no file scan for the application. Open it, Scan files, wait for the answer, then Find rules on the review |
| Use this rule stops at “a rule approver confirms it next” | Separation of duties: the person who chose the rule, or who recorded the Board decision, cannot approve it. Another Rule approver opens the review and selects Approve rule, or an administrator waives separation of duties for a small team (Admin → App Control) |
| Propose refused: “Choose the base policy this allow rule extends” | No event named the blocking policy and no base policy is known for the devices. Pick a base in the Base policy list (add it to Policies or an expected set if it is missing) |
| A script shows hash not available, or a package says “plain SHA-256 values with no Authenticode hash on record” | Built before the script-hash fix. Update the API (scans already on record then work) or install the new agent and run Scan files again. Delete the failed package with reset ticked for the application, build the rule again on the Board, then build the package |
| Package is a Draft: devices reported different Authenticode hashes for a file | Devices disagree about the same file (tampering, a broken agent or a bad import). Check those devices, scan the application again, or retire the rule |
| No folder rule offered for an application on drive D: (or any drive other than C:) | By design: App Control path rules name only the system drive, and other drives are often writable by users. Use a signer or hash rule |
| Package Approve refused | You built it (separation of duties), it has errors, a rule was reopened or retired since the build, or a rule has no simulation as approved |
| Windows ignores the supplemental | The base lacks Enabled:Allow Supplemental Policies, or the deployed base ID differs. Add the base to App Control → Policies so builds check it |
| Ring gate stays Waiting with 0 reporting, or converged stays low | The ring’s tags match no device that reports App Control (check Effective policy inventory and the tags on Devices), or devices have not received the policy: check the Intune assignment and check-in, then Full posture sync |
| Ring gate Stop | More blocks or affected devices than the ring allows, or a critical application was blocked. Review Applications → Blocked now, remove the ring’s assignment in Intune and Roll back |
| Pass ring or Validate refused “needs a view of every device” | Your access is limited by device tags; someone with access to all devices must do it |
| Recertify approval not offered | Only for an approval that still stands, and only for a Board member who is not the application owner. Exceptions and denials: Reopen and decide again |
| Register CSV returns 403 | Needs an App Control governance permission or Admin; the refusal is in the Activity log |
| A file scan is gone from an application | A newer successful scan on that device replaced it, or it is older than AppControlFileScanRetentionDays (180) |
| Impact shows every device Unknown or Stale inventory | Devices known only from Advanced Hunting imports, Policy inventory off, no GetWdacStatus answer yet, or older than AppControlStaleAfterHours; refresh posture. Rule would not apply everywhere: the target base is not active there or does not allow supplemental policies |
| Applications stays empty | Application inventory / Local events off, or the device policy FleetAppControlReportingEnabled is not 1 (the device does not register the operation, so the request fails as unsupported), or the worker has not run since the answers arrived (see Ingested). Use Full posture sync to ask again now. While the catalog is empty the page lists each step (module, devices opted in, requests, answers stored, ingestion) with OK, Waiting or Missing; fix the first Missing one |
An action is missing on a review, or 403 naming separation of duties | Only actions you hold the Board permission for are offered. Whoever opened the review, its owner and its reviewers cannot decide it; ask another Board member, or (small teams) waive separation of duties in settings |
409 on a review action | Someone else changed the review first, or the action no longer applies to its state. The page reloads; try again |
| Import rejects rows | The CSV needs Timestamp, DeviceId, ActionType, FileName and SHA256 columns. Action types that are not App Control audit or block events are skipped with a warning |
| Activity log shows object IDs, not names | Names are recorded from the first action each person takes after the round 6 schema; earlier rows keep the ID |
413 on any request | The body exceeds 256 KB. Only the App Control policy upload (policy XML up to 8 MiB) and the Advanced Hunting import (8 MB CSV) accept more; split or trim anything else |
| Device registered but never Active | AutoApproveAgents = false (approve it in the portal), or RequireEnrollment = true with no secret delivered |