{"id":"19e45c0f22388764","repo":"mongodb/node-mongodb-native","slug":"azure-kms-error-message","errorCode":null,"errorMessage":"[Azure KMS] ${error.message}","messagePattern":"\\[Azure KMS\\] (.+?)","errorType":"exception","errorClass":"MongoCryptAzureKMSRequestError","httpStatus":null,"severity":"error","filePath":"src/client-side-encryption/providers/azure.ts","lineNumber":167,"sourceCode":" * @internal\n *\n * `AzureKMSRequestOptions` allows prose tests to modify the http request sent to the idms\n * servers.  This is required to simulate different server conditions.  No options are expected to\n * be set outside of tests.\n *\n * exposed for CSFLE\n * [prose test 18](https://github.com/mongodb/specifications/tree/master/source/client-side-encryption/tests#azure-imds-credentials)\n */\nexport async function fetchAzureKMSToken(\n  options: AzureKMSRequestOptions = {}\n): Promise<AzureTokenCacheEntry> {\n  const { headers, url } = prepareRequest(options);\n  try {\n    const response = await get(url, { headers });\n    return await parseResponse(response);\n  } catch (error) {\n    if (error instanceof MongoNetworkTimeoutError) {\n      throw new MongoCryptAzureKMSRequestError(`[Azure KMS] ${error.message}`);\n    }\n    throw error;\n  }\n}\n\n/**\n * @internal\n *\n * @throws Will reject with a `MongoCryptError` if the http request fails or the http response is malformed.\n */\nexport async function loadAzureCredentials(kmsProviders: KMSProviders): Promise<KMSProviders> {\n  const azure = await tokenCache.getToken();\n  return { ...kmsProviders, azure };\n}\n","sourceCodeStart":149,"sourceCodeEnd":182,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/client-side-encryption/providers/azure.ts#L149-L182","documentation":"Re-thrown when fetching the Azure IMDS token fails with a MongoNetworkTimeoutError; the original timeout message is wrapped with an '[Azure KMS]' prefix and converted to a MongoCryptAzureKMSRequestError. This surfaces cases where the HTTP GET to 169.254.169.254 did not return in time. Other (non-timeout) errors propagate unchanged.","triggerScenarios":"In fetchAzureKMSToken() catch block when the underlying get() rejects with MongoNetworkTimeoutError; happens when the connection to IMDS times out (default socket timeout).","commonSituations":"IMDS endpoint unreachable or slow (host firewall, Azure platform issue, running off-Azure); tight socketTimeoutMS on the MongoClient flowing into KMS fetch; network namespace/Docker bridge blocking link-local 169.254.169.254; local dev machine that black-holes the address causing slow failure rather than fast refusal.","solutions":["Confirm reachability with a timed curl: curl -v --max-time 5 -H 'Metadata: true' 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net'","If not on Azure, supply explicit azure KMS provider credentials to bypass IMDS entirely.","On Docker/Kubernetes, ensure the network allows link-local traffic (169.254.0.0/16).","Raise socketTimeoutMS / timeoutMS if the IMDS hop is legitimately slow."],"exampleFix":"// before: off-Azure host, IMDS times out\nconst client = new MongoClient(uri, { autoEncryption: { kmsProviders: {}, keyVaultNamespace } });\n\n// after: explicit credentials skip IMDS\nconst kmsProviders = { azure: { tenantId, clientId, clientSecret } };\nconst client = new MongoClient(uri, { autoEncryption: { kmsProviders, keyVaultNamespace } });","handlingStrategy":"try-catch","validationCode":"// Probe IMDS latency before relying on it under a tight timeout.\nasync function imdsLatencyOk(timeoutMs = 2000): Promise<boolean> {\n  const start = Date.now();\n  try {\n    const controller = new AbortController();\n    const t = setTimeout(() => controller.abort(), timeoutMs);\n    await fetch('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net', { headers: { Metadata: 'true' }, signal: controller.signal });\n    clearTimeout(t);\n    return Date.now() - start < timeoutMs;\n  } catch { return false; }\n}","typeGuard":"import { MongoCryptAzureKMSRequestError } from 'mongodb';\nfunction isAzureKMSTimeout(e: unknown): boolean {\n  return e instanceof MongoCryptAzureKMSRequestError && /^\\[Azure KMS\\]/.test(e.message);\n}","tryCatchPattern":"try {\n  await client.connect();\n} catch (err) {\n  if (err instanceof MongoCryptAzureKMSRequestError && /\\[Azure KMS\\]/.test(err.message)) {\n    // Switch to explicit azure credentials or raise socketTimeoutMS.\n  }\n}","preventionTips":["Allow link-local traffic (169.254.0.0/16) in container/network policies.","Don't set socketTimeoutMS too low when using CSFLE on Azure.","Prefer explicit azure KMS credentials off-Azure."],"tags":["csfle","azure-kms","network","timeout","queryable-encryption"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}