Skip to content

InvalidAuthenticationToken (Microsoft Graph): the token was rejected

Short answer: InvalidAuthenticationToken means Microsoft Graph would not accept the access token in the Authorization header. The message after it says why: a missing header, a token for a different audience, a bad signature, or an expired token. It is always HTTP 401, and it is about the token itself, never about which permissions the token carries.

Fix: Read the message, not just the code. `Invalid audience` means request the token for `https://graph.microsoft.com/.default`, not your own API. `Signature is invalid` or `could not be read` means the Authorization header is malformed or truncated. For an expired token, acquire a new one; do not retry the same token. Full steps

At a glance
Error codeInvalidAuthenticationToken
HTTP status401
In Microsoft's Graph error documentationNo (checked ). The wording on this page is what Graph returned in the lab.
CategoryTokens and sessions
Attack signalLow: usually configuration or user error

What does InvalidAuthenticationToken mean?

Section titled “What does InvalidAuthenticationToken mean?”

Microsoft Graph could not accept the bearer token you sent. The HTTP status is 401 and the error code is always the same string, so the code alone tells you very little. The message field is where the information is, and the six messages below are different faults with different fixes.

Microsoft’s current Graph error reference lists HTTP status codes only and contains no table of named error codes, so there is no current Microsoft page defining this string. The only Microsoft page a search of learn.microsoft.com for "InvalidAuthenticationToken" found is an archived TechNet wiki article, marked NOINDEX and is_archived, which records a fifth message — CompactToken parsing failed with error code: 80049217 — and gives a cause worth remembering: “In most cases, the problem is caused by the wrong Authorization key value, i.e., Bearer{{AccessToken}} instead of Bearer {{AccessToken}}, with a space between the word Bearer and the Access Token.” The retired Azure AD Graph catalogue defines two narrower codes instead of this one, Authentication_ExpiredToken and Authentication_MissingOrMalformed. The wording on this page is what Graph v1.0 returned in a lab tenant on 31 October 2026.

An important distinction: this error is about the token, not about what the token is allowed to do. A perfectly valid token that lacks the right permission gives you a 403 and a different code — Authorization_RequestDenied, AccessDenied or Authentication_MSGraphPermissionMissing. If you are looking at a 401, stop checking your app registration’s API permissions; the token never got as far as that check.

On 31 October 2026 automated runs sent six deliberately broken requests to GET /users?$top=1 against a lab tenant. All six returned HTTP 401 with code InvalidAuthenticationToken and these messages:

What was sent message
A token acquired for a different audience (api://AzureADTokenExchange) Access token validation failure. Invalid audience.
A valid token with its last six characters replaced Signature is invalid.
No Authorization header at all Access token is empty.
Authorization: Bearer with an empty value UnableToParseTokens
Authorization: Bearer not-a-token Protocol 'Bearer' failed to validate because The token could not be read.
Authorization: Basic bGFiOmxhYg== Protocol 'Bearer' failed to validate because The token could not be read.

Two things worth noting from those rows.

A missing header and an empty value are different errors. Omitting the header entirely returned Access token is empty.; sending Authorization: Bearer with nothing after it returned the bare string UnableToParseTokens. That distinction is useful and easy to lose: the first says the header never arrived, the second says it arrived carrying nothing. An earlier run conflated them by sending an empty bearer value under a scenario labelled “no header”, which is why both rows are here and labelled by what was actually transmitted.

The last two rows are the same message. A non-Bearer scheme (Basic) and a Bearer value that is not a JWT are indistinguishable from the response. If your client is sending the wrong scheme, nothing in the error says so.

The only innerError field set recorded across these runs was request-id, client-request-id and date. Keep the request id — it is what Microsoft support asks for, and the only reliable way to find one specific failed call afterwards.

On its own, no. The overwhelming majority of these are a client sending a token for the wrong audience, or a cached token that has expired.

The one pattern worth noticing is Invalid audience at volume from something that should not be calling Graph at all. A token that is valid, signed by your tenant, and issued for a different resource is a token that was obtained legitimately and then replayed somewhere it does not belong — which is normal when a developer has copied the wrong scope into a config file, and not normal when it comes from a workload you did not expect to see.

Graph request failures do not appear in Entra sign-in logs: the sign-in that produced the token does, but the rejected Graph call does not. The calls themselves land in MicrosoftGraphActivityLogs, where 401s are findable by status: KQL for rejected tokens.

Invalid audience. You asked for a token for the wrong resource. For client credentials, the scope is https://graph.microsoft.com/.default. For delegated flows, request Graph scopes such as User.Read, not scopes that belong to your own API. A single token cannot be valid for both your API and Graph; acquire two.

Signature is invalid. The token was altered or truncated between issue and use. Common causes: a header length limit cutting the string, string interpolation dropping a character, or logging code that redacts part of the value before it is sent. Print the token’s length at the point of use and compare it with the length at the point of acquisition.

Access token is empty. No Authorization header arrived at all. Check the header is set on the request that is actually sent rather than on a copy of it, and whether a proxy or gateway in front of Graph is stripping it.

UnableToParseTokens. The header arrived with nothing after Bearer . That is what an unset or empty variable interpolated into the header produces, so check the value where the request is sent rather than where it was built.

The token could not be read. The header exists but its value is not a readable JWT. Confirm the scheme is Bearer , with the space after it — Microsoft’s archived note on this code says a missing space is the most common cause, and Bearer<token> is exactly what string concatenation produces when the trailing space is dropped from a constant. Then confirm the value is the raw token and not JSON, not quoted, and not base64-encoded a second time.

CompactToken parsing failed with error code: 80049217. Not seen in the lab run, but recorded by Microsoft for this code. Same family of causes: the header value is not a token Graph can parse.

An expired token. Acquire a new one rather than retrying. If you are caching tokens, refresh on expiry rather than on failure; a retry loop against an expired token is just a slower failure.

Sources

  1. Microsoft Graph error responses and resource types
  2. How to solve error code InvalidAuthenticationToken (archived TechNet wiki)
  3. Azure AD Graph error codes and error handling (retired)