{
  "schemaVersion": "1.0",
  "code": "700003",
  "name": null,
  "title": "AADSTS700003: Device object was not found in the tenant (fix)",
  "url": "https://brambrinkmeier.com/entra/aadsts/700003/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/700003.md",
    "json": "https://brambrinkmeier.com/api/aadsts/700003.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/700003/"
  },
  "description": "AADSTS700003: the device used to sign in was deleted from the tenant. Not in Microsoft's reference. How to re-register it, find who deleted it, KQL.",
  "summary": "AADSTS700003 means the device used for the sign-in no longer exists in the user's home tenant, usually because an admin or a cleanup job deleted it. Microsoft's error reference doesn't list it, but a Microsoft troubleshooting article does. Low attack value. The fix is to re-register or re-join the device; the audit log shows who deleted it.",
  "inMicrosoftReference": false,
  "unlistedChecked": "2026-10-30",
  "meaningText": "Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700003 (checked 30 October 2026).\n\nMicrosoft documents it in a troubleshooting article. When you sign in to an app integrated with Microsoft Entra ID, you get AADSTS700003 with one of these messages:\n\n> Device object was not found in the tenant '\\<TenantName\\>' directory.\n\n> Your organization has deleted this device.\n\nMicrosoft's cause: *\"This issue occurs because the device object is deleted on your home tenant. When a device is deleted, the \"Delete device\" activity type is recorded in the Microsoft Entra audit log.\"* The article covers all three ways a device gets an identity: Microsoft Entra registered, Microsoft Entra joined and Microsoft Entra hybrid joined.\n\nOur reading: the device still holds credentials tied to its old device object, such as its Primary Refresh Token, and tries to use them. Entra can't find the object, so it refuses. This is the deleted-device counterpart of [135011](https://brambrinkmeier.com/entra/aadsts/135011/), where the device object still exists but is disabled.\n\nUsers report it in places that aren't obviously device-bound. An Atlassian knowledge base article describes a Jira Data Center mailbox connected through OAuth 2.0 that stopped sending and receiving mail, with this in the log:\n\n> AADSTS700003: Device object was not found in the tenant 'xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx' directory.\n\nAtlassian's fix was to regenerate the OAuth credentials and tokens and apply them in Jira again. Atlassian attributes the cause to a Microsoft security fix; Microsoft's article doesn't mention one. On Microsoft Q&A, a user hit \"Error code 700003\" in Microsoft Teams on a family computer that, they said, the school district's IT had removed.",
  "sections": [
    {
      "heading": "What does AADSTS700003 mean?",
      "text": "Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700003 (checked 30 October 2026).\n\nMicrosoft documents it in a troubleshooting article. When you sign in to an app integrated with Microsoft Entra ID, you get AADSTS700003 with one of these messages:\n\n> Device object was not found in the tenant '\\<TenantName\\>' directory.\n\n> Your organization has deleted this device.\n\nMicrosoft's cause: *\"This issue occurs because the device object is deleted on your home tenant. When a device is deleted, the \"Delete device\" activity type is recorded in the Microsoft Entra audit log.\"* The article covers all three ways a device gets an identity: Microsoft Entra registered, Microsoft Entra joined and Microsoft Entra hybrid joined.\n\nOur reading: the device still holds credentials tied to its old device object, such as its Primary Refresh Token, and tries to use them. Entra can't find the object, so it refuses. This is the deleted-device counterpart of [135011](https://brambrinkmeier.com/entra/aadsts/135011/), where the device object still exists but is disabled.\n\nUsers report it in places that aren't obviously device-bound. An Atlassian knowledge base article describes a Jira Data Center mailbox connected through OAuth 2.0 that stopped sending and receiving mail, with this in the log:\n\n> AADSTS700003: Device object was not found in the tenant 'xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx' directory.\n\nAtlassian's fix was to regenerate the OAuth credentials and tokens and apply them in Jira again. Atlassian attributes the cause to a Microsoft security fix; Microsoft's article doesn't mention one. On Microsoft Q&A, a user hit \"Error code 700003\" in Microsoft Teams on a family computer that, they said, the school district's IT had removed."
    },
    {
      "heading": "Is it an attack?",
      "text": "Usually not. It follows a device deletion, which is normal cleanup.\n\n| Pattern | Likely meaning |\n|---|---|\n| 700003 for several users the day after a stale-device cleanup | The cleanup removed devices that were still in use. Check the audit log for who ran it. |\n| 700003 for one user after a reinstall or device swap | The old device object was deleted while something still used it. Re-register the device. |\n| 700003 from a server-side integration | A token tied to a device was stored by a service. Atlassian's fix: create new tokens. |\n| 700003 after you deleted a device during incident response | Probably the device you removed, still trying to sign in. Its IP in the sign-in rows shows where it is. |"
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "Microsoft doesn't document which sign-in table 700003 is logged in. Check where it lands first:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700003\"\n| summarize Rows = count() by SourceTable\n```\n\nWho is affected and from where. `DeviceDetail` is dynamic in `SigninLogs` and a string in `AADNonInteractiveUserSignInLogs`, so each leg parses it first. Property names come from the Graph `deviceDetail` resource; we don't know whether they are filled in for a device that no longer exists:\n\n```kusto\nlet rows =\n    union\n        (SigninLogs | extend D = parse_json(tostring(DeviceDetail)) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D),\n        (AADNonInteractiveUserSignInLogs | extend D = parse_json(DeviceDetail) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D);\nrows\n| where TimeGenerated > ago(14d)\n| where ResultType == \"700003\"\n| extend DeviceId = tostring(D.deviceId), DeviceName = tostring(D.displayName), OS = tostring(D.operatingSystem)\n| summarize Rows = count(), Apps = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n          by UserPrincipalName, DeviceId, DeviceName, OS\n| sort by FirstSeen asc\n```\n\nWho deleted devices, and when. Microsoft's article names the audit activity **Delete device**. `TargetResources` and `InitiatedBy` are dynamic columns; the property paths below follow their usual shape, so check them against one row of your own before you rely on them:\n\n```kusto\nAuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName == \"Delete device\"\n| extend DeviceName = tostring(TargetResources[0].displayName),\n         DeviceObjectId = tostring(TargetResources[0].id),\n         ByUser = tostring(InitiatedBy.user.userPrincipalName),\n         ByApp = tostring(InitiatedBy.app.displayName)\n| project TimeGenerated, DeviceName, DeviceObjectId, ByUser, ByApp, Result, LoggedByService\n| sort by TimeGenerated desc\n```\n\nLine up the `FirstSeen` time from the second query with the deletions in the third. A deletion shortly before the first 700003 for that user is your cause."
    },
    {
      "heading": "How do I fix AADSTS700003?",
      "text": "**For the user:** tell IT. Microsoft's article says to *\"engage the home tenant administrators to determine when and why your device object is deleted.\"* If IT agrees the device should stay, re-register it with the steps below. On a school or work device you don't manage, don't do this on your own.\n\n**For admins:** find the deletion with the third query. Then, if the device should stay, have the user re-register or re-join it. Microsoft's steps by join type:\n\n| Join type | Microsoft's steps |\n|---|---|\n| Microsoft Entra registered, Windows 10/11 | **Settings** > **Accounts** > **Access Work or School**, select the account, **Disconnect**, then register the device again. |\n| Microsoft Entra registered, iOS and Android | In Microsoft Authenticator, **Settings** > **Device Registration** > **Unregister device**, then register again. |\n| Microsoft Entra registered, macOS | Use Intune Company Portal to unenroll the device and remove the registration, then register again. |\n| Microsoft Entra joined | In an elevated PowerShell console, run the command below, select **Sign in** and sign in with the Entra ID account. |\n| Microsoft Entra hybrid joined | In an elevated PowerShell console, run the command below, reboot, and sign in with the domain credential. |\n\nMicrosoft Entra joined:\n\n```powershell\ndsregcmd /forcerecovery\n```\n\nMicrosoft Entra hybrid joined:\n\n```powershell\ndsregcmd /leave\n```\n\nFor a hybrid joined device, our reading is that the device registers again through the normal hybrid join process after the reboot. Check that a new device object appears.\n\n**For developers and integration owners:** a stored token that fails with 700003 won't recover. Re-authorize the connection to get new tokens, as Atlassian recommends for Jira mailboxes.\n\n**To prevent it:** our suggestion is to check sign-in activity before a stale-device cleanup deletes a device, and to disable before you delete. A disabled device fails with [135011](https://brambrinkmeier.com/entra/aadsts/135011/) instead, which gives you a window to undo the change before the object is gone."
    }
  ],
  "microsoftWording": {
    "text": "Device object was not found in the tenant '\\<TenantName\\>' directory.",
    "source": "Quoted on the page from the lab or from user reports; the code is not in Microsoft's error code reference",
    "sourceUrl": null
  },
  "securityReading": {
    "category": {
      "id": "device",
      "label": "Devices"
    },
    "kind": {
      "id": "failure",
      "label": "Failure"
    },
    "attackSignal": {
      "level": "low",
      "label": "Low: usually configuration or user error"
    },
    "mitre": [],
    "tables": [],
    "isItAnAttack": "Usually not. It follows a device deletion, which is normal cleanup.\n\n| Pattern | Likely meaning |\n|---|---|\n| 700003 for several users the day after a stale-device cleanup | The cleanup removed devices that were still in use. Check the audit log for who ran it. |\n| 700003 for one user after a reinstall or device swap | The old device object was deleted while something still used it. Re-register the device. |\n| 700003 from a server-side integration | A token tied to a device was stored by a service. Atlassian's fix: create new tokens. |\n| 700003 after you deleted a device during incident response | Probably the device you removed, still trying to sign in. Its IP in the sign-in rows shows where it is. |",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "Microsoft doesn't document which sign-in table 700003 is logged in. Check where it lands first:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700003\"\n| summarize Rows = count() by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Who is affected and from where. `DeviceDetail` is dynamic in `SigninLogs` and a string in `AADNonInteractiveUserSignInLogs`, so each leg parses it first. Property names come from the Graph `deviceDetail` resource; we don't know whether they are filled in for a device that no longer exists:",
      "query": "let rows =\n    union\n        (SigninLogs | extend D = parse_json(tostring(DeviceDetail)) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D),\n        (AADNonInteractiveUserSignInLogs | extend D = parse_json(DeviceDetail) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D);\nrows\n| where TimeGenerated > ago(14d)\n| where ResultType == \"700003\"\n| extend DeviceId = tostring(D.deviceId), DeviceName = tostring(D.displayName), OS = tostring(D.operatingSystem)\n| summarize Rows = count(), Apps = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n          by UserPrincipalName, DeviceId, DeviceName, OS\n| sort by FirstSeen asc"
    },
    {
      "title": null,
      "leadIn": "Who deleted devices, and when. Microsoft's article names the audit activity **Delete device**. `TargetResources` and `InitiatedBy` are dynamic columns; the property paths below follow their usual shape, so check them against one row of your own before you rely on them:",
      "query": "AuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName == \"Delete device\"\n| extend DeviceName = tostring(TargetResources[0].displayName),\n         DeviceObjectId = tostring(TargetResources[0].id),\n         ByUser = tostring(InitiatedBy.user.userPrincipalName),\n         ByApp = tostring(InitiatedBy.app.displayName)\n| project TimeGenerated, DeviceName, DeviceObjectId, ByUser, ByApp, Result, LoggedByService\n| sort by TimeGenerated desc"
    }
  ],
  "kqlSectionText": "Microsoft doesn't document which sign-in table 700003 is logged in. Check where it lands first:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700003\"\n| summarize Rows = count() by SourceTable\n```\n\nWho is affected and from where. `DeviceDetail` is dynamic in `SigninLogs` and a string in `AADNonInteractiveUserSignInLogs`, so each leg parses it first. Property names come from the Graph `deviceDetail` resource; we don't know whether they are filled in for a device that no longer exists:\n\n```kusto\nlet rows =\n    union\n        (SigninLogs | extend D = parse_json(tostring(DeviceDetail)) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D),\n        (AADNonInteractiveUserSignInLogs | extend D = parse_json(DeviceDetail) | project TimeGenerated, ResultType, UserPrincipalName, AppDisplayName, IPAddress, UserAgent, D);\nrows\n| where TimeGenerated > ago(14d)\n| where ResultType == \"700003\"\n| extend DeviceId = tostring(D.deviceId), DeviceName = tostring(D.displayName), OS = tostring(D.operatingSystem)\n| summarize Rows = count(), Apps = make_set(AppDisplayName, 10), IPs = make_set(IPAddress, 10),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n          by UserPrincipalName, DeviceId, DeviceName, OS\n| sort by FirstSeen asc\n```\n\nWho deleted devices, and when. Microsoft's article names the audit activity **Delete device**. `TargetResources` and `InitiatedBy` are dynamic columns; the property paths below follow their usual shape, so check them against one row of your own before you rely on them:\n\n```kusto\nAuditLogs\n| where TimeGenerated > ago(30d)\n| where OperationName == \"Delete device\"\n| extend DeviceName = tostring(TargetResources[0].displayName),\n         DeviceObjectId = tostring(TargetResources[0].id),\n         ByUser = tostring(InitiatedBy.user.userPrincipalName),\n         ByApp = tostring(InitiatedBy.app.displayName)\n| project TimeGenerated, DeviceName, DeviceObjectId, ByUser, ByApp, Result, LoggedByService\n| sort by TimeGenerated desc\n```\n\nLine up the `FirstSeen` time from the second query with the deletions in the third. A deletion shortly before the first 700003 for that user is your cause.",
  "fix": {
    "short": "Admin: find the Delete device event in the audit log. If the device should stay, have the user re-register or re-join it (Entra joined: dsregcmd /forcerecovery; hybrid joined: dsregcmd /leave, then reboot). Integration owner: re-authorize the connection. User: tell IT.",
    "steps": "**For the user:** tell IT. Microsoft's article says to *\"engage the home tenant administrators to determine when and why your device object is deleted.\"* If IT agrees the device should stay, re-register it with the steps below. On a school or work device you don't manage, don't do this on your own.\n\n**For admins:** find the deletion with the third query. Then, if the device should stay, have the user re-register or re-join it. Microsoft's steps by join type:\n\n| Join type | Microsoft's steps |\n|---|---|\n| Microsoft Entra registered, Windows 10/11 | **Settings** > **Accounts** > **Access Work or School**, select the account, **Disconnect**, then register the device again. |\n| Microsoft Entra registered, iOS and Android | In Microsoft Authenticator, **Settings** > **Device Registration** > **Unregister device**, then register again. |\n| Microsoft Entra registered, macOS | Use Intune Company Portal to unenroll the device and remove the registration, then register again. |\n| Microsoft Entra joined | In an elevated PowerShell console, run the command below, select **Sign in** and sign in with the Entra ID account. |\n| Microsoft Entra hybrid joined | In an elevated PowerShell console, run the command below, reboot, and sign in with the domain credential. |\n\nMicrosoft Entra joined:\n\n```powershell\ndsregcmd /forcerecovery\n```\n\nMicrosoft Entra hybrid joined:\n\n```powershell\ndsregcmd /leave\n```\n\nFor a hybrid joined device, our reading is that the device registers again through the normal hybrid join process after the reboot. Check that a new device object appears.\n\n**For developers and integration owners:** a stored token that fails with 700003 won't recover. Re-authorize the connection to get new tokens, as Atlassian recommends for Jira mailboxes.\n\n**To prevent it:** our suggestion is to check sign-in activity before a stale-device cleanup deletes a device, and to disable before you delete. A disabled device fails with [135011](https://brambrinkmeier.com/entra/aadsts/135011/) instead, which gives you a window to undo the change before the object is gone."
  },
  "labReproduced": null,
  "labSectionText": null,
  "labRuns": [],
  "verification": "documentation",
  "related": [
    "135011",
    "50097",
    "53000",
    "50173",
    "5000611"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "Error AADSTS700003 - Device object was not found in the tenant '<TenantName>' directory",
      "url": "https://learn.microsoft.com/en-us/troubleshoot/entra/entra-id/app-integration/error-code-aadsts700003-device-object-not-found"
    },
    {
      "title": "Failure to connect to Office365 mail box due to AADSTS700003 (Atlassian KB)",
      "url": "https://support.atlassian.com/jira/kb/failure-to-connect-to-office365-mail-box-due-to-aadsts700003-device-object-was-not-found-in-the-tenant/"
    },
    {
      "title": "Error code 700003 (Microsoft Q&A 2278445)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/2278445/error-code-700003"
    },
    {
      "title": "deviceDetail resource type (Microsoft Graph)",
      "url": "https://learn.microsoft.com/en-us/graph/api/resources/devicedetail"
    },
    {
      "title": "AuditLogs table reference (Azure Monitor)",
      "url": "https://learn.microsoft.com/azure/azure-monitor/reference/tables/auditlogs"
    },
    {
      "title": "SigninLogs table reference (Azure Monitor)",
      "url": "https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs"
    }
  ],
  "published": "2026-10-30",
  "lastUpdated": "2026-10-30",
  "lastVerified": null,
  "license": "CC BY 4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "licenseNote": "CC BY 4.0 covers the author's own text and classification fields. Quoted Microsoft error wording belongs to Microsoft, is quoted with its source and can change.",
  "attribution": "Bram Brinkmeier, \"AADSTS700003: Device object was not found in the tenant (fix)\", https://brambrinkmeier.com/entra/aadsts/700003/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=700003"
}
