Skip to content

ManagedIdentityCredential failed for 4 days on Flex Consumption while a raw node:http GET to $IDENTITY_ENDPOINT returned 200 — since self-resolved, cause unknown #39566

Description

Summary

On an Azure Functions Flex Consumption app (Linux, Node 20, Central India),
ManagedIdentityCredential.getToken() failed on every call, on every instance, for four days
2026-08-06 20:03 UTC to 2026-08-10 14:34 UTC. No deployment, no configuration change and no SDK
version change preceded it.

Throughout that window, a plain node:http GET to the same $IDENTITY_ENDPOINT, with the same
api-version and the same X-IDENTITY-HEADER, returned HTTP 200 — issued from inside the same
worker process, on the failure path, moments after the SDK call failed.

We worked around it by calling the documented MSI REST endpoint directly. On 2026-08-12 we
re-tested the SDK in isolation and it now works, on the same package versions that failed. We can
no longer reproduce it and we never found the cause. Reporting it because the SDK failed where raw
HTTP on the identical request succeeded, which points at the library regardless of the trigger.

The error

CredentialUnavailableError: ManagedIdentityCredential: Network unreachable.
Message: network_error: Network request failed
  at .../@azure/identity/dist/commonjs/credentials/managedIdentityCredential/index.js:209:27
[cause]: ClientAuthError: network_error: Network request failed
  at createClientAuthError (.../@azure/msal-node/lib/msal-node.cjs:856:12)
  at AppService.acquireTokenWithManagedIdentity (.../@azure/msal-node/lib/msal-node.cjs:11865)

Last success 20:01:28 UTC, first failure 20:05:00 UTC, then zero successes in four days
across roughly 1,100 attempts. Six weeks of clean operation before it.

The key observation — raw HTTP worked the whole time

We deployed a diagnostic that, on the failure path, issues a plain node:http GET to the same
endpoint with the same api-version and header msal uses. From inside the same worker, at the same
moment as the failure:

[MI-DIAG] env presence: {"IDENTITY_ENDPOINT":true,"IDENTITY_HEADER":true,
                         "MSI_ENDPOINT":true,"MSI_SECRET":true,
                         "WEBSITE_SITE_NAME":"<app>"}
[MI-DIAG] endpoint origin: http://169.254.255.2:8081
[MI-DIAG] probe REACHED the endpoint — HTTP 200

The local token service was healthy and reachable from the process. Only the SDK's path failed.

It has since self-resolved

On 2026-08-12 we deployed a throwaway endpoint that calls the SDK cold, from a module sharing no state
with our own token code, with the raw-HTTP control in the same request on the same worker:

Check Result
raw node:http$IDENTITY_ENDPOINT ok, 353 ms, 1852-char token
new ManagedIdentityCredential().getToken(scope) ok, 22 ms, 1852-char token
new DefaultAzureCredential().getToken(scope) ok, 3 ms (in-process cache hit off the line above)

Identical package versions to the failure. Identical endpoint. No proxy variables. Nothing on our side
changed in between that touches this path.

What we ruled out, each with an artifact

Ruled out Evidence
Our code Last deploy 30 h before the break; every CI run in the window audited — none deployed near it
Our usage of the SDK The failing call was new ManagedIdentityCredential().getToken(scope) with no options. The 2026-08-12 probe runs the identical call and succeeds — a static code defect cannot self-repair
SDK version change as the cause Lockfile untouched since 2026-07-02; CI uses npm ci
SDK version change as the fix Reproduced identically on @azure/msal-node 3.8.6 and 5.5.0 during the outage
Configuration change Azure Activity Log: zero control-plane writes in the window, or for 3.5 days after — and we have changed nothing since, yet it now works
Identity misconfiguration All four of IDENTITY_ENDPOINT, IDENTITY_HEADER, MSI_ENDPOINT, MSI_SECRET present throughout
Network / endpoint down Raw node:http GET to the same URL returned HTTP 200
Restart Performed. No change.
VNet / IP restrictions None configured (vnet: null, no IP rules)
Proxy environment variables None present. Logged explicitly: [MI] proxy env present: none
Subscription limits Enabled, spending limit off, billing continuous through the break

Where we think the difference lies (unproven)

@azure/identity replaces msal-node's own HTTP client:

// @azure/identity .../msal/nodeFlows/msalClient.js
system: {
    networkClient: httpClient,
}

msal-node on its own uses require('http') — which is what our working probe used. The injected
client is built on @azure/core-rest-pipeline. Something in that pipeline failed on a request plain
node:http completed against the same host and port, for four days, then stopped failing.

Our first hypothesis was proxyPolicy reading HTTP_PROXY/HTTPS_PROXY, since node:http ignores
those. We disproved it in production — no proxy variables are set. We have no replacement
hypothesis, which is why we are reporting rather than guessing.

The endpoint is a link-local address (169.254.255.2:8081). If anything in the pipeline treats
link-local differently — DNS, agent selection, IPv6 preference, connection reuse, TLS assumptions —
that seems the place to look.

A separate, still-live bug found while diagnosing

msal-node.cjs:12061-62 reads IDENTITY_ENDPOINT and IDENTITY_HEADER once and caches them on the
source object at construction:

this.identityEndpoint = identityEndpoint;
this.identityHeader = identityHeader;

Microsoft's own documentation states the platform rotates IDENTITY_HEADER
(learn.microsoft.com/azure/app-service/overview-managed-identity → REST endpoint reference). Caching
it at construction is a latent staleness bug independent of everything above, and it is still present.

What would actually help

We cannot reproduce this, so we are not asking for a fix we can verify. The useful thing only you can
do: correlate 2026-08-06 ~20:03 UTC, Azure Functions Flex Consumption, Central India, against your
own telemetry
— anything that changed in the managed-identity path, the worker network namespace, or
core-rest-pipeline's behaviour on link-local addresses in that window.

Failing that, the IDENTITY_HEADER caching above is actionable on its own.

Environment

  • @azure/identity 4.13.0 (failing) and 4.13.1 (failing then, working 2026-08-12)
  • @azure/msal-node 3.8.6 and 5.5.0 — both failed
  • @azure/core-rest-pipeline 1.22.2
  • Node 20, Linux, Azure Functions Flex Consumption FC1, 2048 MB, Central India
  • System-assigned managed identity, unchanged throughout (same principalId)
  • Target resource: https://ossrdbms-aad.database.windows.net (Azure Database for PostgreSQL, Entra auth)

Metadata

Metadata

Labels

Azure.IdentityClientThis issue points to a problem in the data-plane of the library.

Type

No type

Projects

Status
Untriaged

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions