IntuneTroubleshooting

Intune automation with Microsoft Graph: fixing 401, 403 and 429 throttling errors

Why Intune scripts on Microsoft Graph fail with 401, 403 Forbidden or 429 Too Many Requests: permission types, admin consent, Intune roles, the 2025 scripts permission change, paging and retries.

Scripts that read or change Intune through Microsoft Graph usually fail in one of three ways: 401 (no usable token), 403 (a token without the right permission, or an admin without the right Intune role) and 429 (too many requests). The responses look alike, but the fixes don't. In this post I'll decode each one, show how to check what your token really carries, and add the paging and retry logic that keeps long exports alive.

Errors this guide fixes

  • Application is not authorized to perform this operationGraph response (403 Forbidden)
  • Insufficient privileges to complete the operation.Graph 403 (Authorization_RequestDenied)
  • InvalidAuthenticationTokenGraph response (401 Unauthorized)
  • 429 Too Many RequestsGraph response (Retry-After header)
  • 503 Service UnavailableGraph response (mobileApps listing)
  • AADSTS65001: The user or administrator has not consented to use the applicationConnect-MgGraph sign-in
How this guide is organised: Symptoms → Why it happens → How to fix it → Verify the fix → Prevent it next timeFlow diagram of the article's sections in reading order: 1. Symptoms. 2. Why it happens. 3. How to fix it (6 steps: Check what the token carries; Request the permission the endpoint needs; Check the scripts permission change; Delegated calls: the admin's Intune role still applies; Page through results and back off on 429; Choose beta or v1.0 deliberately). 4. Verify the fix. 5. Prevent it next time. Toolbox: AADSTS65001, Retry-After, Get-MgContext, Get-MgBeta, .ReadWrite.All.1Symptoms2Why it happens3How to fix it4Verify the fix5Prevent it nexttime1Check what thetoken carries2Request thepermission th…3Check thescripts permi…4Delegatedcalls: the adm…5Page throughresults and b…6Choose beta orv1.0 deliberat…TOOLBOXAADSTS65001Retry-AfterGet-MgContextGet-MgBeta.ReadWrite.AllHow this guide is organised: Symptoms → Why it happens → How to fix it → Verify the fix → Prevent it next timeFlow diagram of the article's sections in reading order: 1. Symptoms. 2. Why it happens. 3. How to fix it (6 steps: Check what the token carries; Request the permission the endpoint needs; Check the scripts permission change; Delegated calls: the admin's Intune role still applies; Page through results and back off on 429; Choose beta or v1.0 deliberately). 4. Verify the fix. 5. Prevent it next time. Toolbox: AADSTS65001, Retry-After, Get-MgContext, Get-MgBeta, .ReadWrite.All.1Symptoms2Why it happens3How to fix it1Check what the token carries2Request the permission the endpoint needs3Check the scripts permission change4Delegated calls: the admin's Intune role stillapplies5Page through results and back off on 4296Choose beta or v1.0 deliberately4Verify the fix5Prevent it next timeTOOLBOXAADSTS65001Retry-AfterGet-MgContextGet-MgBeta.ReadWrite.All
At a glance: how this guide is organised · 6 fix steps · 5 key tools

Symptoms#

A 403 from an Intune endpoint looks like this (IDs and URL shortened):

JSON
{
  "error": {
    "code": "Forbidden",
    "message": "Application is not authorized to perform this operation - Operation ID (for customer support): ... - Activity ID: ... - Url: https://....manage.microsoft.com/..."
  }
}

Other responses that show up in the same scripts:

  • 401 Unauthorized with the code InvalidAuthenticationToken.
  • 403 with the error code Authorization_RequestDenied and the message Insufficient privileges to complete the operation. (two separate fields in the JSON), from the Microsoft Entra parts of a script (users, groups, devices), not from Intune.
  • 429 Too Many Requests, usually with a Retry-After header.
  • 503 Service Unavailable when listing apps under deviceAppManagement/mobileApps with large pages.
  • At sign-in: AADSTS65001: The user or administrator has not consented to use the application.

Why it happens#

ResponseUsual cause
401 InvalidAuthenticationTokenNo token, an expired token in a long-running job, or a token issued for another resource
403 "Application is not authorized…"The token lacks the Intune permission for that endpoint: wrong scope, delegated and application permissions mixed up, or admin consent never granted
403 with permissions that look rightA delegated call made by an admin whose Intune role doesn't allow the action, or a script endpoint still using the old permission (see step 3)
403 Authorization_RequestDeniedMissing directory permission (for example on groups or devices) or Microsoft Entra role
429Too many requests from the app or tenant in a short window; Intune has its own limits on top of the global Graph limits, per app and per tenant, with lower limits for writes (POST, PUT, PATCH, DELETE)
503 on mobileAppsThe page of apps is too large

Microsoft states that all Intune permission scopes require administrator access, so an admin must grant consent, and a delegated script also needs a user with matching Intune role permissions.

How to fix it#

1. Check what the token carries#

PowerShell
Connect-MgGraph -Scopes 'DeviceManagementManagedDevices.Read.All' -NoWelcome
Get-MgContext | Select-Object AuthType, ClientId, Account, Scopes

AuthType tells you whether you're Delegated or AppOnly; Scopes lists what was actually granted. If you call REST with your own token, decode it: delegated permissions appear in the scp claim, application permissions in roles.

2. Request the permission the endpoint needs#

PowerShell
Find-MgGraphCommand -Command Get-MgDeviceManagementManagedDevice |
    Select-Object -First 1 -ExpandProperty Permissions
TaskPermission
Read managed devicesDeviceManagementManagedDevices.Read.All
Wipe, retire, remote lock, rebootDeviceManagementManagedDevices.PrivilegedOperations.All
Configuration profiles, compliance policiesDeviceManagementConfiguration.Read.All / .ReadWrite.All
Apps, app protection, app configurationDeviceManagementApps.Read.All / .ReadWrite.All
Scripts and RemediationsDeviceManagementScripts.Read.All / .ReadWrite.All
Enrollment, Apple tokens, connectorsDeviceManagementServiceConfig.Read.All / .ReadWrite.All
Intune roles and assignmentsDeviceManagementRBAC.Read.All / .ReadWrite.All

For an app registration, add these under API permissions › Add a permission › Microsoft Graph as Application permissions for unattended jobs or Delegated permissions for interactive use, then grant admin consent. For interactive Microsoft Graph PowerShell, an admin has to consent to the scopes once; otherwise users hit AADSTS65001 or an approval prompt.

3. Check the scripts permission change#

Since 31 July 2025, Microsoft Graph uses the DeviceManagementScripts permissions instead of DeviceManagementConfiguration for deviceManagementScripts, deviceHealthScripts (Remediations), deviceShellScripts, deviceComplianceScripts and deviceCustomAttributeShellScripts. Automation that read or uploaded scripts before that date can now get 403 until you add and consent to the new permission.

4. Delegated calls: the admin's Intune role still applies#

The Intune admin center itself works through Microsoft Graph, so a delegated script can only do what the signed-in admin could do in the portal. A role without the action returns 403, and scope tags limit which objects come back, so a short device list can be RBAC rather than a bug (see Intune RBAC and scope tags). Application permissions have no signed-in admin; Intune role assignments target users and groups, so the Graph permission you grant is the whole boundary. Grant the least you need.

5. Page through results and back off on 429#

Intune list endpoints return results in pages. Follow @odata.nextLink (or use -All on SDK cmdlets), and use $select to keep pages small:

PowerShell
$uri = 'v1.0/deviceManagement/managedDevices?$select=id,deviceName,complianceState,lastSyncDateTime'
$devices = @(while ($uri) {
    $page = Invoke-MgGraphRequest -Method GET -Uri $uri
    $page.value
    $uri = $page.'@odata.nextLink'
})
"Devices retrieved: $($devices.Count)"

The Microsoft Graph SDKs already retry throttled requests using Retry-After or exponential backoff, but requests inside a JSON batch aren't retried automatically. If you call REST directly, honour the header yourself (PowerShell 7):

PowerShell
function Invoke-GraphWithRetry ($Uri, $Headers, $MaxAttempts = 5) {
    for ($i = 1; $i -le $MaxAttempts; $i++) {
        try { return Invoke-RestMethod -Uri $Uri -Headers $Headers -ErrorAction Stop }
        catch {
            $resp = $_.Exception.Response
            if (-not $resp -or [int]$resp.StatusCode -ne 429 -or $i -eq $MaxAttempts) { throw }
            $wait = $resp.Headers.RetryAfter.Delta.TotalSeconds
            if (-not $wait) { $wait = [math]::Pow(2, $i) * 5 }   # no header: back off
            Start-Sleep -Seconds $wait
        }
    }
}

Microsoft's guidance is to fall back to exponential backoff whenever a 429 arrives without a Retry-After header, hence the fallback. For app listings that return 503, Microsoft recommends a smaller page size, such as $top=20.

6. Choose beta or v1.0 deliberately#

Many Intune endpoints and properties exist only in beta (Microsoft.Graph.Beta, cmdlets named Get-MgBeta…). Beta can change without notice, so pin module versions and re-test after updates. To find the exact call behind a portal blade, watch the browser's developer tools network tab while you use the Intune admin center.

Verify the fix#

  • Get-MgContext shows the expected AuthType and the new scope.
  • The same request returns 200, and record counts match what the Intune admin center shows for that admin.
  • A full export completes with no unhandled 429; log how often your retry waited.
  • For app-only jobs, the service principal sign-ins in the Microsoft Entra sign-in logs show successful sign-ins for the app.

Prevent it next time#

  • Use one app registration per automation, least-privilege permissions and certificate credentials, as in Automating Intune device reports with Microsoft Graph PowerShell.
  • Avoid per-device GET loops; filter on the server, select only needed properties and run writes sequentially.
  • Watch Microsoft's permission changes (like the scripts change) and the Intune limits on the throttling limits page.

References#

Revision history: Oct 2026 — re-checked against Microsoft Learn: 2 corrections; 1 detail reworded or labelled as reported by admins.

Written and checked against current Microsoft Learn documentation. Test changes with a pilot group before rolling them out to everyone, and if an admin center path has moved since, search for the setting name instead.

Spotted a mistake, or did this fix work differently for you? Email me or message me on LinkedIn — corrections are credited in the article.

Written by

Omer Eltayeb

Intune Subject Matter Expert in Cairo, Egypt, former Microsoft Cloud Solutions Architect, Microsoft Certified Trainer and Microsoft Innovative Educator Expert (2024–26) and Microsoft Elevate Educator Expert (2026–27). I share practical, step-by-step guides, study plans, scripts and toolkits for Microsoft Intune, Configuration Manager, Microsoft Entra ID, Microsoft Defender, Exchange and Microsoft 365 with the community.

Microsoft Certified Trainer (MCT) 2026Microsoft Innovative Educator Expert 2025–2026Microsoft Elevate Educator Expert 2026–2027ISC2 Certified Information Systems Security Professional (CISSP)Microsoft 365 Certified: Enterprise Administrator Expert (MS-102)