{
  "schemaVersion": "1.0",
  "code": "700024",
  "name": null,
  "title": "AADSTS700024: Client assertion is not within its valid time range (fix)",
  "url": "https://brambrinkmeier.com/entra/aadsts/700024/",
  "alternates": {
    "markdown": "https://brambrinkmeier.com/entra/aadsts/700024.md",
    "json": "https://brambrinkmeier.com/api/aadsts/700024.json",
    "html": "https://brambrinkmeier.com/entra/aadsts/700024/"
  },
  "description": "AADSTS700024: the client assertion or federated token was expired or not yet valid. Not in Microsoft's error list. Fixes for CI/CD, KQL.",
  "summary": "AADSTS700024 means an app signed in with a client assertion (a signed JWT, or a federated token from GitHub Actions or Azure DevOps) that was expired or not yet valid. Microsoft's error reference doesn't list it. The usual cause is a long CI/CD job that reuses its first token. Low attack value. Fetch a fresh token right before each use.",
  "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 AADSTS700024 (checked 30 October 2026).\n\nThe lab reproduced it. A client-credentials request used a GitHub Actions OIDC token as the client assertion (through a federated credential), sent after that token had expired. Entra returned:\n\n> AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z\n\nThe lab's record cuts the message at about 160 characters, so the rest of the line is missing here. A user on [Microsoft Q&A](https://learn.microsoft.com/en-us/answers/questions/778031/client-assertion-is-not-within-its-valid-time-rang) posted a full message with the expiry time instead: *\"Current time: 2022-03-18T11:28:52.5620799Z, expiry time of assertion 2022-03-15T11:56:47.0000000Z.\"* A later reply in the same thread quotes both *\"assertion valid from\"* and *\"expiry\"*. The exact wording of the second half varies between reports. Either way, compare the times in it with the `nbf` and `exp` of the token you sent.\n\nA **client assertion** is a signed token the app sends instead of a client secret. It is either a JWT the app signs with its own certificate, or a token from another identity provider that a federated credential trusts, such as GitHub Actions or Azure DevOps. Microsoft's certificate credentials page describes its time claims. `nbf` is *\"the time before which the JWT MUST NOT be accepted\"* and `exp` is *\"the expiration time on or after which the JWT must not be accepted\"*. 700024 means the current time is outside that window.\n\nMicrosoft does document the code on another page. Its Azure DevOps workload identity troubleshooting page lists:\n\n> **AADSTS700024: Client assertion is not within its valid time range**\n>\n> If the error happens after approximately 1 hour, use a service connection with Workload identity federation and a Managed Identity instead. [...] If the error happens before 1 hour but after 10 minutes, move commands that (implicitly) request an access token to e.g. access Azure storage to the beginning of your script.",
  "sections": [
    {
      "heading": "What does AADSTS700024 mean?",
      "text": "Microsoft's [error code reference](https://learn.microsoft.com/entra/identity-platform/reference-error-codes) doesn't list AADSTS700024 (checked 30 October 2026).\n\nThe lab reproduced it. A client-credentials request used a GitHub Actions OIDC token as the client assertion (through a federated credential), sent after that token had expired. Entra returned:\n\n> AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z\n\nThe lab's record cuts the message at about 160 characters, so the rest of the line is missing here. A user on [Microsoft Q&A](https://learn.microsoft.com/en-us/answers/questions/778031/client-assertion-is-not-within-its-valid-time-rang) posted a full message with the expiry time instead: *\"Current time: 2022-03-18T11:28:52.5620799Z, expiry time of assertion 2022-03-15T11:56:47.0000000Z.\"* A later reply in the same thread quotes both *\"assertion valid from\"* and *\"expiry\"*. The exact wording of the second half varies between reports. Either way, compare the times in it with the `nbf` and `exp` of the token you sent.\n\nA **client assertion** is a signed token the app sends instead of a client secret. It is either a JWT the app signs with its own certificate, or a token from another identity provider that a federated credential trusts, such as GitHub Actions or Azure DevOps. Microsoft's certificate credentials page describes its time claims. `nbf` is *\"the time before which the JWT MUST NOT be accepted\"* and `exp` is *\"the expiration time on or after which the JWT must not be accepted\"*. 700024 means the current time is outside that window.\n\nMicrosoft does document the code on another page. Its Azure DevOps workload identity troubleshooting page lists:\n\n> **AADSTS700024: Client assertion is not within its valid time range**\n>\n> If the error happens after approximately 1 hour, use a service connection with Workload identity federation and a Managed Identity instead. [...] If the error happens before 1 hour but after 10 minutes, move commands that (implicitly) request an access token to e.g. access Azure storage to the beginning of your script."
    },
    {
      "heading": "Reproduced in the lab",
      "text": "On 30 October 2026 the lab ran a GitHub Actions job that signs in to my lab tenant through a federated credential. It sent a client-credentials token request with the job's OIDC token as the client assertion, after the token had expired. Entra returned `AADSTS700024`, first line quoted above.\n\nAn earlier lab run the same day sent the same kind of request about 60 seconds after `exp` and got a token back ([lab run issue](https://github.com/GrantZero604/Brambrinkmeier.com/issues/64)); the run above waited about 11 minutes. Our reading: Entra allows some clock skew. Two runs don't show where the limit is, and Microsoft doesn't publish one.\n\nThe message gives the current time and the start of the token's validity, 16 minutes apart. That makes it easy to see how old the assertion was. It lands in **`AADServicePrincipalSignInLogs`**: two rows (one per run), Failure. On the failed rows the client credential type is \"none\", while the app's successful sign-ins show \"federatedIdentityCredential\", so don't filter on that field to find these. Entra's explanation on the row reads: *\"The app used an expired client assertion. It needs to be updated in the Azure Portal to generate a new client secret or certificate.\"* That advice doesn't fit a federated credential, as far as we can tell; the fix is a fresh assertion, as below. The row's failure reason is a template with placeholders (`{curTime}`, `{validTime}`, `{expTime}`); the real times are only in the error the app got. The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). The first two queries found the rows. The unfamiliar-IP query returned nothing, which is correct here: both failing IPs also had successful sign-ins."
    },
    {
      "heading": "Is it an attack?",
      "text": "Usually no. It is a timing problem in the app or pipeline.\n\n| Pattern | Likely meaning |\n|---|---|\n| A GitHub Actions or Azure DevOps job fails partway through, after its first Azure commands worked | The job outlived its federated token. A reply in the Azure/login repository says the GitHub token's *\"lifetime of it is 5 mins\"* ([issue #441](https://github.com/Azure/login/issues/441)). Users report failures once Azure CLI runs past about 10 minutes ([issue #372](https://github.com/Azure/login/issues/372)). |\n| Azure DevOps fails after about 1 hour, or between 10 minutes and 1 hour | The two cases Microsoft's DevOps page describes, quoted above. |\n| An app with a self-signed certificate assertion fails on every request | In Q&A 778031 the expiry in the message stayed days in the past while the user's code set a fresh one. Our reading: the app sends a cached or reused assertion, sets `nbf`/`exp` wrongly, or runs on a host whose clock or time zone is off. A reply in that thread suspects time zones. |\n| 700024 from an IP that never signs in successfully for that app | Possibly an old assertion replayed from somewhere else (unconfirmed). Entra rejected it, but a leaked token means something leaked. Check where it came from. |"
    },
    {
      "heading": "How do I find it in my logs (KQL)?",
      "text": "Microsoft doesn't document which sign-in table 700024 is logged in. An app signing in as itself should land in `AADServicePrincipalSignInLogs` (our lab rows did), but check where it lands in your workspace:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700024\"\n| summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId\n```\n\nWhich apps fail, with which credential type and federated credential. `FederatedCredentialId` is documented as the ID of *\"an application's federated identity credential if a federated identity credential was used to sign in\"*. Next to the failures, the query counts the same app's successes, which shows whether a job got its first tokens before failing:\n\n```kusto\nlet fails =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(7d)\n    | where ResultType == \"700024\"\n    | summarize Failures = count(), LastFail = max(TimeGenerated), FailIPs = make_set(IPAddress, 10)\n              by AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId;\nlet wins =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(7d)\n    | where ResultType == \"0\"\n    | summarize Successes = count() by AppId;\nfails\n| join kind=leftouter wins on AppId\n| project AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId, Failures, Successes, LastFail, FailIPs\n| sort by Failures desc\n```\n\n700024 from IP addresses that never succeed for that app may point to replay. Runners with changing IPs produce false positives, so treat hits as a starting point:\n\n```kusto\nlet goodIPs =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(30d)\n    | where ResultType == \"0\"\n    | distinct AppId, IPAddress;\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"700024\"\n| join kind=leftanti goodIPs on AppId, IPAddress\n| summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress\n| sort by Attempts desc\n```"
    },
    {
      "heading": "How do I fix AADSTS700024?",
      "text": "**For developers:**\n1. **GitHub Actions:** request Azure tokens early, or log in again before late steps that need Azure. Users in [issue #372](https://github.com/Azure/login/issues/372) report that Azure CLI does not refresh the ID token on its own. A community workaround there re-runs `az login` with a fresh federated token every 240 seconds. Splitting a long job into shorter jobs should also work, as each job gets its own token. We haven't tested this.\n2. **Azure DevOps:** follow Microsoft's two cases quoted above. Past about 1 hour, use workload identity federation with a managed identity. Between 10 minutes and 1 hour, move the commands that need a token to the start of the script, so the cached access token covers the rest.\n3. **Self-signed assertions:** build a new assertion for each token request. Microsoft's certificate credentials page says to use the current time for `nbf` and to keep `exp` *\"short - 5-10 minutes after `nbf` at most\"*.\n4. **Clock:** a host clock that runs ahead or behind likely gives the same error even with a fresh assertion (unconfirmed). Keep the clock in sync.\n\n**For admins:**\n1. Find the app with the queries above and give its owner the time of the failures.\n2. Check whether the failures sit late in long pipeline runs. If so, it is the token lifetime, not the federated credential setup.\n3. If failures come from IPs your pipelines don't use, find out how the assertion got there."
    }
  ],
  "microsoftWording": {
    "text": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z",
    "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": "app-config",
      "label": "App configuration"
    },
    "kind": {
      "id": "failure",
      "label": "Failure"
    },
    "attackSignal": {
      "level": "low",
      "label": "Low: usually configuration or user error"
    },
    "mitre": [],
    "tables": [],
    "isItAnAttack": "Usually no. It is a timing problem in the app or pipeline.\n\n| Pattern | Likely meaning |\n|---|---|\n| A GitHub Actions or Azure DevOps job fails partway through, after its first Azure commands worked | The job outlived its federated token. A reply in the Azure/login repository says the GitHub token's *\"lifetime of it is 5 mins\"* ([issue #441](https://github.com/Azure/login/issues/441)). Users report failures once Azure CLI runs past about 10 minutes ([issue #372](https://github.com/Azure/login/issues/372)). |\n| Azure DevOps fails after about 1 hour, or between 10 minutes and 1 hour | The two cases Microsoft's DevOps page describes, quoted above. |\n| An app with a self-signed certificate assertion fails on every request | In Q&A 778031 the expiry in the message stayed days in the past while the user's code set a fresh one. Our reading: the app sends a cached or reused assertion, sets `nbf`/`exp` wrongly, or runs on a host whose clock or time zone is off. A reply in that thread suspects time zones. |\n| 700024 from an IP that never signs in successfully for that app | Possibly an old assertion replayed from somewhere else (unconfirmed). Entra rejected it, but a leaked token means something leaked. Check where it came from. |",
    "conditionalAccess": null
  },
  "kql": [
    {
      "title": null,
      "leadIn": "Microsoft doesn't document which sign-in table 700024 is logged in. An app signing in as itself should land in `AADServicePrincipalSignInLogs` (our lab rows did), but check where it lands in your workspace:",
      "query": "union withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700024\"\n| summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId"
    },
    {
      "title": null,
      "leadIn": "Which apps fail, with which credential type and federated credential. `FederatedCredentialId` is documented as the ID of *\"an application's federated identity credential if a federated identity credential was used to sign in\"*. Next to the failures, the query counts the same app's successes, which shows whether a job got its first tokens before failing:",
      "query": "let fails =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(7d)\n    | where ResultType == \"700024\"\n    | summarize Failures = count(), LastFail = max(TimeGenerated), FailIPs = make_set(IPAddress, 10)\n              by AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId;\nlet wins =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(7d)\n    | where ResultType == \"0\"\n    | summarize Successes = count() by AppId;\nfails\n| join kind=leftouter wins on AppId\n| project AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId, Failures, Successes, LastFail, FailIPs\n| sort by Failures desc"
    },
    {
      "title": null,
      "leadIn": "700024 from IP addresses that never succeed for that app may point to replay. Runners with changing IPs produce false positives, so treat hits as a starting point:",
      "query": "let goodIPs =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(30d)\n    | where ResultType == \"0\"\n    | distinct AppId, IPAddress;\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"700024\"\n| join kind=leftanti goodIPs on AppId, IPAddress\n| summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress\n| sort by Attempts desc"
    }
  ],
  "kqlSectionText": "Microsoft doesn't document which sign-in table 700024 is logged in. An app signing in as itself should land in `AADServicePrincipalSignInLogs` (our lab rows did), but check where it lands in your workspace:\n\n```kusto\nunion withsource=SourceTable SigninLogs, AADNonInteractiveUserSignInLogs, AADServicePrincipalSignInLogs\n| where TimeGenerated > ago(30d)\n| where ResultType == \"700024\"\n| summarize Rows = count(), LastSeen = max(TimeGenerated) by SourceTable, AppId\n```\n\nWhich apps fail, with which credential type and federated credential. `FederatedCredentialId` is documented as the ID of *\"an application's federated identity credential if a federated identity credential was used to sign in\"*. Next to the failures, the query counts the same app's successes, which shows whether a job got its first tokens before failing:\n\n```kusto\nlet fails =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(7d)\n    | where ResultType == \"700024\"\n    | summarize Failures = count(), LastFail = max(TimeGenerated), FailIPs = make_set(IPAddress, 10)\n              by AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId;\nlet wins =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(7d)\n    | where ResultType == \"0\"\n    | summarize Successes = count() by AppId;\nfails\n| join kind=leftouter wins on AppId\n| project AppId, ServicePrincipalName, ClientCredentialType, FederatedCredentialId, Failures, Successes, LastFail, FailIPs\n| sort by Failures desc\n```\n\n700024 from IP addresses that never succeed for that app may point to replay. Runners with changing IPs produce false positives, so treat hits as a starting point:\n\n```kusto\nlet goodIPs =\n    AADServicePrincipalSignInLogs\n    | where TimeGenerated > ago(30d)\n    | where ResultType == \"0\"\n    | distinct AppId, IPAddress;\nAADServicePrincipalSignInLogs\n| where TimeGenerated > ago(7d)\n| where ResultType == \"700024\"\n| join kind=leftanti goodIPs on AppId, IPAddress\n| summarize Attempts = count(), LastSeen = max(TimeGenerated) by AppId, ServicePrincipalName, IPAddress\n| sort by Attempts desc\n```",
  "fix": {
    "short": "Developer: get a fresh token right before each use. GitHub Actions: request Azure tokens early, or run `az login` again before late steps. Azure DevOps past about 1 hour: use workload identity federation with a managed identity. Self-signed JWT: build a new assertion for each request.",
    "steps": "**For developers:**\n1. **GitHub Actions:** request Azure tokens early, or log in again before late steps that need Azure. Users in [issue #372](https://github.com/Azure/login/issues/372) report that Azure CLI does not refresh the ID token on its own. A community workaround there re-runs `az login` with a fresh federated token every 240 seconds. Splitting a long job into shorter jobs should also work, as each job gets its own token. We haven't tested this.\n2. **Azure DevOps:** follow Microsoft's two cases quoted above. Past about 1 hour, use workload identity federation with a managed identity. Between 10 minutes and 1 hour, move the commands that need a token to the start of the script, so the cached access token covers the rest.\n3. **Self-signed assertions:** build a new assertion for each token request. Microsoft's certificate credentials page says to use the current time for `nbf` and to keep `exp` *\"short - 5-10 minutes after `nbf` at most\"*.\n4. **Clock:** a host clock that runs ahead or behind likely gives the same error even with a fresh assertion (unconfirmed). Keep the clock in sync.\n\n**For admins:**\n1. Find the app with the queries above and give its owner the time of the failures.\n2. Check whether the failures sit late in long pipeline runs. If so, it is the token lifetime, not the federated credential setup.\n3. If failures come from IPs your pipelines don't use, find out how the assertion got there."
  },
  "labReproduced": {
    "date": "2026-10-30",
    "method": "ROPC and other token-endpoint requests against a lab tenant",
    "scenario": "Client assertion expired",
    "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z",
    "logCaptured": "2026-10-30",
    "kqlTested": "2026-10-30"
  },
  "labSectionText": "On 30 October 2026 the lab ran a GitHub Actions job that signs in to my lab tenant through a federated credential. It sent a client-credentials token request with the job's OIDC token as the client assertion, after the token had expired. Entra returned `AADSTS700024`, first line quoted above.\n\nAn earlier lab run the same day sent the same kind of request about 60 seconds after `exp` and got a token back ([lab run issue](https://github.com/GrantZero604/Brambrinkmeier.com/issues/64)); the run above waited about 11 minutes. Our reading: Entra allows some clock skew. Two runs don't show where the limit is, and Microsoft doesn't publish one.\n\nThe message gives the current time and the start of the token's validity, 16 minutes apart. That makes it easy to see how old the assertion was. It lands in **`AADServicePrincipalSignInLogs`**: two rows (one per run), Failure. On the failed rows the client credential type is \"none\", while the app's successful sign-ins show \"federatedIdentityCredential\", so don't filter on that field to find these. Entra's explanation on the row reads: *\"The app used an expired client assertion. It needs to be updated in the Azure Portal to generate a new client secret or certificate.\"* That advice doesn't fit a federated credential, as far as we can tell; the fix is a fresh assertion, as below. The row's failure reason is a template with placeholders (`{curTime}`, `{validTime}`, `{expTime}`); the real times are only in the error the app got. The KQL below was run on these rows ([how](https://brambrinkmeier.com/methodology/)). The first two queries found the rows. The unfamiliar-IP query returned nothing, which is correct here: both failing IPs also had successful sign-ins.",
  "labRuns": [
    {
      "date": "2026-10-30",
      "run": "round 4",
      "method": "token-endpoint requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/67",
      "scenario": "Client assertion expired",
      "expected": "700024",
      "got": "700024",
      "matchedExpectation": true,
      "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T21:40:51.4941498Z, assertion valid from 2026-10-30T21:24:51.0000000Z"
    },
    {
      "date": "2026-10-30",
      "run": "round 5",
      "method": "token-endpoint requests against a lab tenant, using lab-created test apps",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/69",
      "scenario": "Client assertion expired",
      "expected": "700024",
      "got": "700024",
      "matchedExpectation": true,
      "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T22:30:55.4651851Z, assertion valid from 2026-10-30T22:14:55.0000000Z"
    },
    {
      "date": "2026-10-30",
      "run": "round 5 (first attempt)",
      "method": "token-endpoint requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/68",
      "scenario": "Client assertion expired",
      "expected": "700024",
      "got": "700024",
      "matchedExpectation": true,
      "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T22:11:38.3450502Z, assertion valid from 2026-10-30T21:55:38.0000000Z"
    },
    {
      "date": "2026-10-30",
      "run": "round 6",
      "method": "token-endpoint requests against a lab tenant, using lab-created test apps",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/70",
      "scenario": "Client assertion expired",
      "expected": "700024",
      "got": "700024",
      "matchedExpectation": true,
      "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T23:01:02.2283272Z, assertion valid from 2026-10-30T22:45:02.0000000Z"
    },
    {
      "date": "2026-10-30",
      "run": "round 7",
      "method": "token-endpoint requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/71",
      "scenario": "Client assertion expired",
      "expected": "700024",
      "got": "700024",
      "matchedExpectation": true,
      "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T23:33:21.4471912Z, assertion valid from 2026-10-30T23:17:21.0000000Z"
    },
    {
      "date": "2026-10-30",
      "run": null,
      "method": "ROPC and other token-endpoint requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/66",
      "scenario": "Client assertion expired",
      "expected": "700024",
      "got": "700024",
      "matchedExpectation": true,
      "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-30T17:08:40.4130764Z, assertion valid from 2026-10-30T16:52:40.0000000Z"
    },
    {
      "date": "2026-10-31",
      "run": "round 8",
      "method": "token-endpoint and device-code requests against a lab tenant",
      "issue": "https://github.com/GrantZero604/Brambrinkmeier.com/issues/72",
      "scenario": "Client assertion expired",
      "expected": "700024",
      "got": "700024",
      "matchedExpectation": true,
      "message": "AADSTS700024: Client assertion is not within its valid time range. Current time: 2026-10-31T00:07:21.2184562Z, assertion valid from 2026-10-30T23:51:21.0000000Z"
    }
  ],
  "verification": "lab-reproduced",
  "related": [
    "7000215",
    "7000222",
    "7000218",
    "700016",
    "50013",
    "50027",
    "90023"
  ],
  "coveredBy": [],
  "sources": [
    {
      "title": "Microsoft Entra authentication and authorization error codes",
      "url": "https://learn.microsoft.com/entra/identity-platform/reference-error-codes"
    },
    {
      "title": "Troubleshoot an Azure Resource Manager workload identity service connection (Azure DevOps)",
      "url": "https://learn.microsoft.com/en-us/azure/devops/pipelines/release/troubleshoot-workload-identity"
    },
    {
      "title": "Microsoft identity platform application authentication certificate credentials",
      "url": "https://learn.microsoft.com/en-ca/entra/identity-platform/certificate-credentials"
    },
    {
      "title": "Microsoft Q&A: Client assertion is not within its valid time range (778031)",
      "url": "https://learn.microsoft.com/en-us/answers/questions/778031/client-assertion-is-not-within-its-valid-time-rang"
    },
    {
      "title": "Azure/login issue #441 (GitHub)",
      "url": "https://github.com/Azure/login/issues/441"
    },
    {
      "title": "Azure/login issue #372 (GitHub)",
      "url": "https://github.com/Azure/login/issues/372"
    },
    {
      "title": "AADServicePrincipalSignInLogs table reference (Azure Monitor)",
      "url": "https://docs.azure.cn/en-us/azure-monitor/reference/tables/AADServicePrincipalSignInLogs"
    }
  ],
  "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, \"AADSTS700024: Client assertion is not within its valid time range (fix)\", https://brambrinkmeier.com/entra/aadsts/700024/ (CC BY 4.0)",
  "microsoftErrorLookup": "https://login.microsoftonline.com/error?code=700024"
}
