Dokploy/dokploy · error · Error

Azure Key Vault: authentication failed (status ${response.st

Error message

Azure Key Vault: authentication failed (status ${response.status}${detail ? `: ${detail}` : ""})

What it means

getAccessToken POSTs credentials to the Azure AD OAuth token endpoint; a non-2xx means authentication failed. The code extracts the first line of error_description for detail, so the message includes Azure's reason (e.g. AADSTS7000215 invalid client secret, AADSTS700016 wrong tenant/app).

Source

Thrown at packages/server/src/utils/vault/azure.ts:33

		client_secret: config.clientSecret,
		scope: "https://vault.azure.net/.default",
	});
	const response = await vaultFetch(
		`https://login.microsoftonline.com/${encodeURIComponent(config.tenantId)}/oauth2/v2.0/token`,
		{
			method: "POST",
			headers: { "Content-Type": "application/x-www-form-urlencoded" },
			body: body.toString(),
		},
	);

	if (!response.ok) {
		let detail = "";
		try {
			const body = (await response.json()) as { error_description?: string };
			detail = (body.error_description ?? "").split("\n")[0] ?? "";
		} catch {}
		throw new Error(
			`Azure Key Vault: authentication failed (status ${response.status}${detail ? `: ${detail}` : ""})`,
		);
	}

	const data = (await response.json()) as { access_token?: string };
	if (!data.access_token) {
		throw new Error("Azure Key Vault: no access token returned");
	}
	return data.access_token;
};

const readSecret = async (config: AzureConfig, token: string, name: string) => {
	const response = await vaultFetch(
		`${baseUrl(config)}/secrets/${encodeURIComponent(name)}?api-version=${API_VERSION}`,
		{ headers: { Authorization: `Bearer ${token}` } },
	);

	if (response.status === 404) {

View on GitHub (pinned to 546686ea35)

Solutions

  1. Match the AADSTS code in the message: AADSTS7000215 → wrong client secret; AADSTS700016 → wrong clientId/tenant; AADSTS70002 → missing/invalid secret
  2. Generate a new client secret in the app registration and update the vault config
  3. Verify tenantId is the directory containing the app registration
  4. Wait a few minutes after adding a new secret — Azure propagation can lag
Defensive patterns

Strategy: retry

Validate before calling

// no safe precheck over network; verify config shape locally first
if (!tenantId || !clientId || !clientSecret) throw new Error('Incomplete Azure vault config');

Type guard

const isCompleteAzureConfig = (c: unknown): c is { tenantId: string; clientId: string; clientSecret: string } =>
  typeof c === 'object' && c !== null &&
  ['tenantId','clientId','clientSecret'].every(k => typeof (c as any)[k] === 'string' && (c as any)[k].length > 0);

Try / catch

try {
  await getAccessToken(cfg);
} catch (e) {
  const msg = String(e);
  if (/AADSTS7000215/.test(msg)) throw new Error('Invalid client secret — rotate it in Azure');
  if (/AADSTS700016/.test(msg)) throw new Error('Wrong clientId or tenantId');
  throw e;
}

Prevention

When it happens

Trigger: Wrong tenantId/clientId/clientSecret, expired or rotated client secret, service principal deleted/disabled, or using login.microsoftonline.com against a national cloud tenant.

Common situations: Secret expired (Azure secrets have expiries) and wasn't rotated; copied tenant ID from the wrong directory; app registration removed.

Understand the failure class

Related errors


AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27). Data as JSON: /api/errors/d79fd0c41814c8ea. Report an issue: GitHub.