Azure OAuth Configuration Troubleshooting
This guide helps you diagnose and resolve Azure App Registration issues that prevent ServiceOps from authenticating with Microsoft 365 mailboxes via OAuth 2.0.
If ServiceOps stops fetching emails, fails to connect to a Microsoft 365 mailbox, or throws OAuth errors after setup, the problem almost always lies in the Azure App Registration. This guide takes you through each configuration area (credentials, API permissions, client secrets, redirect URIs, and consent policies) so you can pinpoint exactly what is misconfigured and fix it. For a quick reference to OAuth error codes and symptoms, see Email Server FAQs.
Prerequisites
Before you begin, ensure you have the following access and information ready.
- You need a Global Administrator or Application Administrator account in Azure
- Have the Client ID from the ServiceOps email server configuration open and ready for comparison
- Know the ServiceOps Base URL of your instance (visible in Admin > Organization > System Preference > Application Settings)
Locating the Motadata Email App in Azure Portal
Finding the correct app registration is the first step. You cannot verify or fix any OAuth configuration without opening the right app.
- Open
https://portal.azure.comand sign in with a Global Administrator account. - Click Microsoft Entra ID in the left navigation. If it is not visible, search for "Entra ID" in the top search bar.
- Click App registrations, then select the All applications tab to see all registered apps, not just ones you own.
- Search for the app by name — typically "Motadata", "ServiceOps", or a custom name set during OAuth setup. Alternatively, paste the Client ID from ServiceOps into the search box.
- Click the app name to open its configuration dashboard.
If the app does not appear, it may be registered in a different Azure tenant. Confirm the Tenant ID in ServiceOps matches the directory you are searching. Also check the Deleted applications tab — a deleted app causes complete OAuth failure and won't appear in the main list.
Troubleshooting Steps
Client ID, Tenant ID, or OAuth Endpoint Mismatch
Possible Reasons:
- The Client ID in ServiceOps does not match the Application (Client) ID in Azure.
- The Tenant ID points to the wrong Microsoft identity endpoint.
- Leading or trailing spaces were introduced when copying credentials manually.
- The v1.0 OAuth endpoint is configured instead of the required v2.0 endpoint.
Solution:
Open App Registration > Overview and verify:
- Application (Client) ID: Copy this GUID and compare it character-for-character with the Client ID in ServiceOps email server OAuth settings. They must match exactly.
- Directory (Tenant) ID: Compare with the Tenant ID in ServiceOps. A wrong Tenant ID sends token requests to the wrong Microsoft identity endpoint.
- Supported account types: For most ServiceOps setups, this should be "Accounts in this organizational directory only (Single tenant)."
Click Endpoints at the top of the Overview page and compare the URLs with the fields in ServiceOps:
| Endpoint | Format | ServiceOps Field |
|---|---|---|
| OAuth 2.0 authorization endpoint (v2) | https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize | Authorization Endpoint URL |
| OAuth 2.0 token endpoint (v2) | https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token | Token Endpoint URL |
The v1.0 endpoints (without /v2.0/) are deprecated. They don't support the permissions model that ServiceOps requires and cause 401 errors when accessing the mailbox.
Copy the Client ID and Tenant ID using the clipboard icon in Azure rather than selecting the text manually. Leading or trailing spaces cause an "application not found" error that's hard to spot.
API Permissions Not Granted or Missing Admin Consent
Possible Reasons:
- One or more required API permissions are missing from the Azure App Registration.
- Admin consent has not been granted for the configured permissions.
Mail.ReadWriteis added as Delegated instead of Application.
Solution:
Navigate to App Registration > API permissions and verify the following permissions are present and consented:
| Permission | Type | Purpose |
|---|---|---|
| Mail.ReadWrite | Microsoft Graph, Application | Allows ServiceOps to read and manage emails in the mailbox. Required for incoming email fetching. |
| Files.Read.All | Microsoft Graph, Delegated | Allows ServiceOps to read all files the signed-in user can access, including email attachments stored in OneDrive or SharePoint. Required when ServiceOps needs to fetch or process file attachments as part of the email handling workflow. |
| offline_access | Microsoft Graph, Delegated | Allows ServiceOps to obtain refresh tokens for long-lived access without repeated sign-in. |
| User.Read | Microsoft Graph, Delegated | Basic user profile read required for the initial OAuth sign-in flow. |
| IMAP.AccessAsUser.All | Office 365 Exchange Online, Delegated | Required only if you use IMAP protocol with OAuth instead of Graph API. |
| SMTP.Send | Office 365 Exchange Online, Delegated | Required only if you use SMTP with OAuth authentication. |
Checking consent status
In the API permissions table, the Status column must show a green checkmark and "Granted for [Your Organization]" for every permission listed.
- If any permission shows "Not granted" or an empty status, admin consent is missing.
- If a required permission doesn't appear in the list at all, click + Add a permission to add it.
Granting admin consent
- On the API permissions page, click Grant admin consent for [Your Organization].
- Click Yes in the confirmation dialog. All permissions update to "Granted for [Organization]" with a green checkmark.
Adding Mail.ReadWrite as Delegated instead of Application is a common mistake. Delegated permissions require an active interactive user session. Application permissions work for background email fetching without a signed-in user. Check the type column carefully.
OAuth Token Request Fails or Token Cannot Access the Mailbox
Possible Reasons:
- The Scope field in ServiceOps is incomplete or contains incorrect permission URIs.
- Scope values contain commas, extra spaces, or line breaks instead of space-separated URIs.
offline_accessis missing from the scope, resulting in no refresh token being issued.
Solution:
Navigate to Admin > Support Channel > Emails > Incoming Email Server (or Outgoing) > OAuth Configuration > Scope field in ServiceOps and verify the scope string matches one of the following:
For Microsoft Graph API (recommended for Microsoft 365, covers MAPI and Graph-based IMAP):
https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/Files.Read.All https://graph.microsoft.com/User.Read offline_access
For IMAP or SMTP with OAuth (legacy protocol):
https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send offline_access
- Every permission URI in the scope string must also be present and admin-consented in the Azure App Registration.
- Scope values are space-separated URIs. Check for commas, extra spaces at the start or end, or line breaks, as any of these cause the token request to fail.
Omitting offline_access from the scope means ServiceOps gets only a short-lived access token (valid for 1 hour) with no refresh token. Email fetching works initially and then stops after the token expires.
OAuth Fails with invalid_client Error
Possible Reasons:
- The client secret configured in ServiceOps has expired.
- A new secret was created in Azure but not updated in ServiceOps.
- The secret was deleted from Azure.
Solution:
Navigate to App Registration > Certificates and secrets > Client secrets tab.
1. Check secret expiry:
- The Client secrets table shows each secret's Description, Expires date, and masked Value.
- If the Expires date is in the past, the secret is expired. The Status column shows "Expired" and the date turns red.
- Renew any secret expiring within 30 days before it causes an outage.
2. Create a new secret:
- Click + New client secret. Enter a description (e.g., "ServiceOps OAuth 2027") and set an expiry of 12 or 24 months. Microsoft no longer allows "Never" as an option.
- Click Add. The secret Value appears only once. Copy it immediately and store it securely, as you cannot retrieve it again after leaving the page.
- Go to the ServiceOps email server configuration and update the Client Secret field with the new value. Save and click Test Connection.
- Delete the old expired secret from Azure after confirming the new one works.
Set a calendar reminder 30 days before the new secret's expiry date. Azure sends no automatic expiry alerts.
If you create a new secret in Azure but don't update it in ServiceOps right away, authentication fails. Always update ServiceOps before closing the Azure session.
OAuth Sign-in Fails with AADSTS50011 Redirect URI Error
Possible Reasons:
- The Redirect URI in Azure does not exactly match the callback URL ServiceOps sends during the OAuth flow.
- A trailing slash,
httpinstead ofhttps, or a typo in the URL causes the mismatch. - "Access tokens" or "ID tokens" are checked under Implicit grant and hybrid flows.
Solution:
Navigate to App Registration > Authentication > Platform configurations > Web > Redirect URIs.
1. Check the redirect URI:
- For Motadata cloud-hosted ServiceOps, the required URL is:
https://demo.serviceops.com/oauth/callback - For self-hosted or on-premise ServiceOps, go to ServiceOps Admin > Support Channels > Emails > Incoming/Outgoing Email Server > OAuth Configuration > Redirect URL and confirm that exact URL appears in the Azure list.
- Check for trailing slashes,
httpvshttps, or any typos. Azure requires a character-perfect match. - Under Implicit grant and hybrid flows, confirm "Access tokens" and "ID tokens" are NOT checked.
2. Fix a missing or incorrect redirect URI:
- Click + Add URI, paste the correct callback URL exactly as it appears in ServiceOps, and click Save.
- If the re-authentication page gets stuck after Microsoft login, open browser developer tools (F12), go to the Network tab, and find the failed redirect request. The URL shown in that request is exactly what needs to be added to Azure.
Keep only the URLs actively in use. Remove old or unused redirect URIs to reduce the attack surface. Use HTTPS only, as Azure does not accept HTTP callback URLs for production apps.
OAuth Authorization Flow Blocked by Admin Consent Policy
Possible Reasons:
- Tenant-wide user consent is disabled, requiring a Global Administrator to perform re-authentication.
- The ServiceOps app has not been consented to in this tenant.
- An admin consent workflow is active, blocking non-admin re-authentication attempts.
Solution:
1. Check Enterprise Application permissions:
Navigate to Azure Active Directory > Enterprise applications, search for and open the ServiceOps app, then click Permissions. The Admin consent tab shows all admin-consented permissions for this tenant. Confirm Mail.ReadWrite, Files.Read.All, and offline_access appear here.
If the app doesn't appear under Enterprise applications, it hasn't been consented to in this tenant. Grant admin consent from App Registration > API permissions.
2. Check tenant-wide consent policy:
- Go to Azure Active Directory > User settings. If "Users can consent to apps accessing company data" is set to No, only admins can consent. Re-authentication in ServiceOps must run as a Global Administrator.
- Go to Azure Active Directory > Enterprise applications > Consent and permissions > User consent settings to see the active consent policy.
- If an admin consent workflow is active, non-admin users who try to re-authenticate trigger an approval request. Admins must approve from Azure AD > Enterprise applications > Admin consent requests.
In most corporate environments, re-authentication in ServiceOps must run as a Global Administrator (not a regular technician or IT support account).
Analyzing Azure Sign-in and Audit Logs
Possible Reasons:
- OAuth failures with no visible error in ServiceOps require Azure AD log analysis to identify the root cause from Microsoft's side.
Solution:
Azure AD maintains detailed sign-in logs for every authentication attempt and audit logs for every configuration change.
1. Where to check:
- Sign-in logs: Azure Active Directory > Monitoring > Sign-in logs
- Audit logs: Azure Active Directory > Monitoring > Audit logs
- App-specific logs: Azure Active Directory > Enterprise applications > [ServiceOps App] > Sign-in logs
2. Reading sign-in logs:
- Filter by Application: paste the Client ID or type the app name. Set the Date range to cover the failure window.
- Look for Status = Failure entries and click any to expand details.
- Note the Error code, Failure reason, and Additional details fields.
Common error codes:
| Error Code | Meaning and Fix |
|---|---|
| AADSTS7000215 | Invalid client secret. The secret in ServiceOps is wrong, deleted from Azure, or superseded by a new one. Update the Client Secret in ServiceOps. |
| AADSTS70011 | Invalid scope. The scope in ServiceOps contains a permission URI not declared in the Azure app registration. Fix the scope string. |
| AADSTS50011 | Redirect URI mismatch. The callback URL ServiceOps sends isn't in the app's Authentication page. Add it to Azure. |
| AADSTS65001 | Admin has not consented. Grant admin consent from App Registration > API permissions. |
| AADSTS700016 | Application not found in directory. The Client ID in ServiceOps doesn't exist in this tenant. Check Client ID and Tenant ID. |
| AADSTS135011 | Device disabled or deleted in Azure AD. The service account associated with authentication has been disabled. |
| AADSTS90072 | User account doesn't exist in the tenant. The account used for OAuth sign-in doesn't belong to the tenant the Tenant ID identifies. |
3. Reading audit logs:
- Filter by Service: "Core Directory" or "Application Management". Filter by Category: "ApplicationManagement".
- Filter by Activity: "Consent to application" to see when consent was granted or revoked.
- Look for events timestamped around when the email server stopped working. A deleted secret, removed permission, or revoked consent appears here.
Sign-in logs older than 30 days aren't available on Azure AD Free tier (90 days on P1/P2). Export logs to Log Analytics for long-term retention if the failure occurred earlier than that window.