{"record":{"id":"0857e9840e6251cc","repo":"n8n-io/n8n","slug":"failed-to-retrieve-oauth2-access-token","errorCode":null,"errorMessage":"Failed to retrieve OAuth2 access token","messagePattern":"Failed to retrieve OAuth2 access token","errorType":"exception","errorClass":"NodeOperationError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/llms/LmChatAzureOpenAi/credentials/N8nOAuth2TokenCredential.ts","lineNumber":47,"sourceCode":"\t\t\t\tscopes: this.credential.scope?.split(' '),\n\t\t\t\tauthentication: this.credential.authentication,\n\t\t\t\tauthorizationUri: this.credential.authUrl,\n\t\t\t\tadditionalBodyProperties: {\n\t\t\t\t\tresource: 'https://cognitiveservices.azure.com/',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tconst token = await oAuthClient.credentials.getToken();\n\t\t\tconst data = token.data as ClientOAuth2TokenData & {\n\t\t\t\texpires_on: number;\n\t\t\t};\n\t\t\treturn {\n\t\t\t\ttoken: data.access_token,\n\t\t\t\texpiresOnTimestamp: data.expires_on,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\t// Re-throw with better error message\n\t\t\tthrow new NodeOperationError(this.node, 'Failed to retrieve OAuth2 access token', error);\n\t\t}\n\t}\n\n\t/**\n\t * Gets the deployment details from the credential\n\t */\n\tasync getDeploymentDetails() {\n\t\treturn {\n\t\t\tapiVersion: this.credential.apiVersion,\n\t\t\tendpoint: this.credential.endpoint,\n\t\t\tresourceName: this.credential.resourceName,\n\t\t};\n\t}\n}\n","sourceCodeStart":29,"sourceCodeEnd":62,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/llms/LmChatAzureOpenAi/credentials/N8nOAuth2TokenCredential.ts#L29-L62","documentation":"Catch-all in N8nOAuth2TokenCredential.getToken(): any error thrown after the access_token existence check (mostly from oAuthClient.credentials.getToken() during refresh/exchange) is wrapped as a NodeOperationError with message 'Failed to retrieve OAuth2 access token' and the original as cause. It exists to translate client-oauth2 library errors into a node-friendly message.","triggerScenarios":"The token exchange/refresh against accessTokenUrl fails — invalid client secret, wrong scope, expired refresh token, network error, Azure Entra endpoint returning an error body, or the additionalBodyProperties 'resource' value rejected by the tenant.","commonSituations":"Client secret rotated in Azure but not updated in n8n; scope missing 'https://cognitiveservices.azure.com/.default'; tenant admin conditional access blocking the token endpoint; accessTokenUrl wrong cloud (public vs gov); clock skew.","solutions":["Inspect the wrapped cause for the Azure error (e.g. invalid_client, invalid_grant) and fix the underlying config.","Reconnect the OAuth2 credential in n8n so a fresh refresh token is stored.","Verify clientId/clientSecret against the Azure app registration and confirm the app is allowed to call Cognitive Services.","Confirm accessTokenUrl and scope match the Azure cloud (public/gov/China) in use."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-flight: ensure client secret and token URL are set\nif (!credential.clientSecret || !credential.accessTokenUrl) {\n  throw new Error('OAuth2 clientSecret and accessTokenUrl are required');\n}","typeGuard":"const isClientOAuthError = (e: unknown): boolean =>\n  /invalid_client|invalid_grant|unauthorized/i.test(e instanceof Error ? e.message : String(e));","tryCatchPattern":"try {\n  return await oAuthClient.credentials.getToken();\n} catch (e) {\n  logger.warn(e);\n  throw new NodeOperationError(node, 'Failed to retrieve OAuth2 access token', e as Error);\n}","preventionTips":["Keep clientId/clientSecret in sync with the Azure app registration.","Refresh tokens promptly; reconnect when refresh fails.","Verify accessTokenUrl/scope match the Azure cloud in use."],"tags":["azure","oauth2","credentials","authentication","token","network"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}