{
  "schemaVersion": "1.0",
  "code": "90014",
  "name": "MissingRequiredField",
  "title": "AADSTS90014 fix: required field missing from the request",
  "url": "https://brambrinkmeier.com/entra/aadsts/90014/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/90014.md",
    "json": "https://brambrinkmeier.com/api/aadsts/90014.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/90014/"
  },
  "description": "AADSTS90014: Entra expected a field that wasn't in the request. The message names it, often 'scope' or 'request'. Add it or fix the flow; KQL.",
  "summary": "AADSTS90014 means Entra expected a field in the request or credential and it wasn't there. The message names the field: users report 'scope' from integrations such as ServiceNow, and 'request' when a browser app navigated back during sign-in. Microsoft gives no more detail. Low attack value. Read the field name and fix the request or the sign-in flow.",
  "inMicrosoftReference": true,
  "unlistedChecked": null,
  "meaningText": "Microsoft's description:\n\n> **MissingRequiredField**: This error code might appear in various cases when an expected field isn't present in the credential.\n\nEntra ID expected a field and didn't find it. Microsoft doesn't list the cases, but the message names the field, and that is where to start. Users report two forms:\n\n- *\"AADSTS90014: The required field 'scope' is missing from the credential\"*, from ServiceNow using OAuth against a Microsoft API.\n- *\"AADSTS90014: The required field 'request' is missing from the credential\"*, from a single-page app signing in through Azure AD B2C, and quoted in a moderator's answer to a user signing in to school or work apps.\n\nCompare [900144](https://brambrinkmeier.com/entra/aadsts/900144/), which says *\"The request body must contain the following parameter\"* and also names what is missing. Microsoft doesn't explain when Entra returns one code and not the other. Either way the fix is to supply what the message names. If the message is about `resource` instead, see [901002](https://brambrinkmeier.com/entra/aadsts/901002/).",
  "sections": [
    {
      "heading": "What does AADSTS90014 mean?",
      "text": "Microsoft's description:\n\n> **MissingRequiredField**: This error code might appear in various cases when an expected field isn't present in the credential.\n\nEntra ID expected a field and didn't find it. Microsoft doesn't list the cases, but the message names the field, and that is where to start. Users report two forms:\n\n- *\"AADSTS90014: The required field 'scope' is missing from the credential\"*, from ServiceNow using OAuth against a Microsoft API.\n- *\"AADSTS90014: The required field 'request' is missing from the credential\"*, from a single-page app signing in through Azure AD B2C, and quoted in a moderator's answer to a user signing in to school or work apps.\n\nCompare [900144](https://brambrinkmeier.com/entra/aadsts/900144/), which says *\"The request body must contain the following parameter\"* and also names what is missing. Microsoft doesn't explain when Entra returns one code and not the other. Either way the fix is to supply what the message names. If the message is about `resource` instead, see [901002](https://brambrinkmeier.com/entra/aadsts/901002/)."
    },
    {
      "heading": "Is it an attack?",
      "text": "No documented attack pattern exists. The request is incomplete and no token is issued.\n\n| Pattern | Likely meaning |\n|---|---|\n| Field `scope`, from an integration or service account | A client credentials (or similar) token request without `scope`. Microsoft marks `scope` as **Required** in the client credentials flow. Configuration. |\n| Field `request`, from a browser app, now and then | In the B2C thread the accepted answer said it *\"can be caused by navigating back after succesfuly loging-in\"*, and the developer confirmed the app navigated back right after sign-in. Our reading: the sign-in response was lost because the app left the page before handling it. |\n| Field `request`, one user, a third-party app | The user pressed Back or reloaded during sign-in, or the app's flow has the same bug. Not an attack. |\n| 90014 from one app, starting right after a release | The new version stopped sending a field. |"
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "Microsoft doesn't document whether or where 90014 is logged. Check all three sign-in tables:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"90014\"\n| summarize Rows = count(), Apps = dcount(AppId) by SourceTable\n```\n\nWhich app is missing which field. We assume `ResultDescription` carries the message with the field name filled in; we haven't seen a logged row:\n\n```kusto\nunion SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"90014\"\n| extend Field = extract(@\"field '([^']+)'\", 1, ResultDescription)\n| summarize Rows = count(), Users = dcount(UserPrincipalName),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n          by AppDisplayName, ServicePrincipalName, AppId, Field\n| sort by Rows desc\n```\n\nApps that produced 90014 today but not in the previous 14 days. A `FirstSeen` right after a deployment points at the release:\n\n```kusto\nlet recent =\n    union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"90014\"\n    | summarize Rows = count(), FirstSeen = min(TimeGenerated) by AppId, AppDisplayName;\nlet before =\n    union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n    | where TimeGenerated between (ago(15d) .. ago(1d))\n    | where ResultType == \"90014\"\n    | distinct AppId;\nrecent\n| join kind=leftanti before on AppId\n| sort by Rows desc\n```\n\n`ResultType` is a **string** column, so compare it with `\"90014\"`, not `90014`. In `AADServicePrincipalSignInLogs` the app name is in `ServicePrincipalName`, not `AppDisplayName`."
    },
    {
      "heading": "How do I fix AADSTS90014?",
      "text": "**For the user:**\n1. Don't press Back or reload while the sign-in page is working. Close the tab and start again from the app.\n2. If it keeps happening, clear the browser's cookies for the site and try again. That was the generic advice in the Q&A thread; one user said it didn't help.\n3. Still failing: report it to IT with the full message, including the field name.\n\n**For developers:**\n1. Read the field name in the error and add it.\n2. `scope` in a client credentials request: send the API's identifier with `.default`, for example `https://graph.microsoft.com/.default`. Microsoft: *\"All scopes included must be for a single resource.\"*\n3. `request` in a browser app: let the app finish processing the sign-in response before it routes or navigates anywhere. The accepted answer in the B2C thread recommended a browser trace of the whole flow to see where it breaks.\n\n**For admins:**\n1. Use the second query to find the app and the field, and send both to the app's owner.\n2. For ServiceNow or another integration with an OAuth profile, check whether the profile sends a scope. ServiceNow documents the 'scope' form of this error in KB0866332."
    }
  ],
  "microsoftWording": {
    "text": "**MissingRequiredField**: This error code might appear in various cases when an expected field isn't present in the credential.",
    "source": "Microsoft's error code reference, as quoted on the page",
    "sourceUrl": "https://learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes"
  },
  "securityReading": {
    "category": {
      "id": "app-config",
      "label": "App configuration"
    },
    "kind": {
      "id": "failure",
      "label": "Failure"
    },
    "attackSignal": {
      "level": "low",
      "label": "Low: usually configuration or user error"
    },
    "mitre": [],
    "tables": [],
    "isItAnAttack": "No documented attack pattern exists. The request is incomplete and no token is issued.\n\n| Pattern | Likely meaning |\n|---|---|\n| Field `scope`, from an integration or service account | A client credentials (or similar) token request without `scope`. Microsoft marks `scope` as **Required** in the client credentials flow. Configuration. |\n| Field `request`, from a browser app, now and then | In the B2C thread the accepted answer said it *\"can be caused by navigating back after succesfuly loging-in\"*, and the developer confirmed the app navigated back right after sign-in. Our reading: the sign-in response was lost because the app left the page before handling it. |\n| Field `request`, one user, a third-party app | The user pressed Back or reloaded during sign-in, or the app's flow has the same bug. Not an attack. |\n| 90014 from one app, starting right after a release | The new version stopped sending a field. |",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "Microsoft doesn't document whether or where 90014 is logged. Check all three sign-in tables:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"90014\"\n| summarize Rows = count(), Apps = dcount(AppId) by SourceTable"
    },
    {
      "title": null,
      "leadIn": "Which app is missing which field. We assume `ResultDescription` carries the message with the field name filled in; we haven't seen a logged row:",
      "query": "union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"90014\"\n| extend Field = extract(@\"field '([^']+)'\", 1, ResultDescription)\n| summarize Rows = count(), Users = dcount(UserPrincipalName),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n          by AppDisplayName, ServicePrincipalName, AppId, Field\n| sort by Rows desc"
    },
    {
      "title": null,
      "leadIn": "Apps that produced 90014 today but not in the previous 14 days. A `FirstSeen` right after a deployment points at the release:",
      "query": "let recent =\n    union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"90014\"\n    | summarize Rows = count(), FirstSeen = min(TimeGenerated) by AppId, AppDisplayName;\nlet before =\n    union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n    | where TimeGenerated between (ago(15d) .. ago(1d))\n    | where ResultType == \"90014\"\n    | distinct AppId;\nrecent\n| join kind=leftanti before on AppId\n| sort by Rows desc"
    }
  ],
  "kqlSectionText": "Microsoft doesn't document whether or where 90014 is logged. Check all three sign-in tables:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"90014\"\n| summarize Rows = count(), Apps = dcount(AppId) by SourceTable\n```\n\nWhich app is missing which field. We assume `ResultDescription` carries the message with the field name filled in; we haven't seen a logged row:\n\n```kusto\nunion SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"90014\"\n| extend Field = extract(@\"field '([^']+)'\", 1, ResultDescription)\n| summarize Rows = count(), Users = dcount(UserPrincipalName),\n            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)\n          by AppDisplayName, ServicePrincipalName, AppId, Field\n| sort by Rows desc\n```\n\nApps that produced 90014 today but not in the previous 14 days. A `FirstSeen` right after a deployment points at the release:\n\n```kusto\nlet recent =\n    union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(1d)\n    | where ResultType == \"90014\"\n    | summarize Rows = count(), FirstSeen = min(TimeGenerated) by AppId, AppDisplayName;\nlet before =\n    union SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n    | where TimeGenerated between (ago(15d) .. ago(1d))\n    | where ResultType == \"90014\"\n    | distinct AppId;\nrecent\n| join kind=leftanti before on AppId\n| sort by Rows desc\n```\n\n`ResultType` is a **string** column, so compare it with `\"90014\"`, not `90014`. In `AADServicePrincipalSignInLogs` the app name is in `ServicePrincipalName`, not `AppDisplayName`.",
  "fix": {
    "short": "Developer: read the field name in the error and add it. For 'scope' in a client credentials request, send `scope=<API URI>/.default`. For 'request', make the app finish handling the sign-in response before it navigates. User: don't press Back during sign-in; start again from the app.",
    "steps": "**For the user:**\n1. Don't press Back or reload while the sign-in page is working. Close the tab and start again from the app.\n2. If it keeps happening, clear the browser's cookies for the site and try again. That was the generic advice in the Q&A thread; one user said it didn't help.\n3. Still failing: report it to IT with the full message, including the field name.\n\n**For developers:**\n1. Read the field name in the error and add it.\n2. `scope` in a client credentials request: send the API's identifier with `.default`, for example `https://graph.microsoft.com/.default`. Microsoft: *\"All scopes included must be for a single resource.\"*\n3. `request` in a browser app: let the app finish processing the sign-in response before it routes or navigates anywhere. The accepted answer in the B2C thread recommended a browser trace of the whole flow to see where it breaks.\n\n**For admins:**\n1. Use the second query to find the app and the field, and send both to the app's owner.\n2. For ServiceNow or another integration with an OAuth profile, check whether the profile sends a scope. ServiceNow documents the 'scope' form of this error in KB0866332."
  },
  "labReproduced": null,
  "labSectionText": null,
  "labRuns": [],
  "verification": "documentation",
  "related": [
    "900144",
    "9002313",
    "90023",
    "901002"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "Microsoft identity platform and the OAuth 2.0 client credentials flow",
      "url": "https://learn.microsoft.com/entra/identity-platform/v2-oauth2-client-creds-grant-flow"
    },
    {
      "title": "SigninLogs table reference (Azure Monitor)",
      "url": "https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/signinlogs"
    },
    {
      "title": "How do I fix a AADSTS90014 error code? (Microsoft Q&A)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/1443443/how-do-i-fix-a-aadsts90014-error-code"
    },
    {
      "title": "AADSTS90014: The required field 'request' is missing (Microsoft Q&A)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/1161763/aadsts90014-the-required-field-request-is-missing"
    },
    {
      "title": "AADSTS90014: The required field 'scope' is missing from the credential (ServiceNow KB0866332)",
      "url": "https://support.servicenow.com/kb?id=kb_article_view&sysparm_article=KB0866332"
    }
  ],
  "published": "2026-11-01",
  "lastUpdated": "2026-11-01",
  "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, \"AADSTS90014 fix: required field missing from the request\", https://brambrinkmeier.com/entra/aadsts/90014/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=90014"
}
