TroubleshootingAuthentication Issues

Authentication Troubleshooting

This guide helps you resolve common authentication issues when using Mission Lens and the M365 Data Exporter.

Common Authentication Errors

AADSTS50011: Invalid Redirect URI

Error Message:

AADSTS50011: The redirect URI 'https://your-app.com/api/auth/callback'
specified in the request does not match the redirect URIs configured
for the application.

Cause: The redirect URI in your application doesn’t match what’s registered in Azure AD.

Solution:

  1. Go to Azure Portal → Azure Active Directory → App registrations
  2. Select your application
  3. Navigate to AuthenticationPlatform configurations
  4. Add the exact redirect URI used by your application:
    • For local development: http://localhost:3000/api/auth/callback
    • For production: https://your-domain.com/api/auth/callback
  5. Click Save

Important: The URI must match exactly, including:

  • Protocol (http vs https)
  • Domain
  • Port number
  • Path (including trailing slash)

AADSTS700016: Application Not Found

Error Message:

AADSTS700016: Application with identifier 'your-client-id' was not found
in the directory 'your-tenant-id'.

Cause: The Application (client) ID is incorrect or the app doesn’t exist in your tenant.

Solution:

  1. Verify your AZURE_CLIENT_ID environment variable:

    echo $AZURE_CLIENT_ID
  2. Go to Azure Portal → Azure Active Directory → App registrations

  3. Find your application and verify the Application (client) ID

  4. Update your .env file:

    AZURE_CLIENT_ID=correct-client-id-here
  5. Restart your application


AADSTS7000215: Invalid Client Secret

Error Message:

AADSTS7000215: Invalid client secret provided.

Cause: The client secret is incorrect, expired, or has been rotated.

Solution:

  1. Go to Azure Portal → Azure Active Directory → App registrations
  2. Select your application → Certificates & secrets
  3. Check if your secret has expired
  4. Create a new client secret:
    • Click + New client secret
    • Add a description (e.g., “Mission Lens Secret - Jan 2025”)
    • Select expiration period (recommended: 6 months for dev, 24 months for prod)
    • Click Add
  5. Copy the Value (not the Secret ID)
  6. Update your .env file:
    AZURE_CLIENT_SECRET=new-secret-value-here
  7. Restart your application

Important: Save the secret value immediately - you won’t be able to retrieve it later.


Error Message:

AADSTS65001: The user or administrator has not consented to use the application.

Cause: The application requires permissions that haven’t been granted by an admin.

Solution:

Option 1: Admin Consent (Recommended)

  1. Go to Azure Portal → Azure Active Directory → App registrations
  2. Select your application → API permissions
  3. Click Grant admin consent for [Your Organization]
  4. Confirm the consent prompt

Option 2: Consent URL

Have an admin visit this URL:

https://login.microsoftonline.com/{tenant-id}/adminconsent
?client_id={client-id}
&redirect_uri={redirect-uri}

Replace:

  • {tenant-id}: Your Azure AD tenant ID
  • {client-id}: Your application client ID
  • {redirect-uri}: Your app’s redirect URI (URL-encoded)

AADSTS50076: Multi-Factor Authentication Required

Error Message:

AADSTS50076: Due to a configuration change made by your administrator,
or because you moved to a new location, you must use multi-factor
authentication to access.

Cause: Your tenant requires MFA for sign-in.

Solution:

For interactive authentication, this is expected - users will complete MFA during sign-in.

For service accounts or background processes:

  1. Use certificate-based authentication instead of client secrets
  2. Create a service account excluded from MFA requirements (requires admin)
  3. Use managed identities in Azure (recommended for production)

AADSTS50020: User Account from External Provider

Error Message:

AADSTS50020: User account 'user@external.com' from identity provider
'live.com' does not exist in tenant 'your-tenant'.

Cause: Trying to sign in with a personal Microsoft account (e.g., @outlook.com, @hotmail.com) when the app only allows organizational accounts.

Solution:

  1. Go to Azure Portal → Azure Active Directory → App registrations

  2. Select your application → Authentication

  3. Under Supported account types, verify the setting:

    • Single tenant: Only accounts in your organization
    • Multitenant: Accounts in any Azure AD directory
    • Multitenant + personal accounts: Includes @outlook.com, @live.com, etc.
  4. For Mission Lens, typically use Single tenant or Multitenant (not personal accounts)


AADSTS650052: Insufficient Permissions

Error Message:

AADSTS650052: The app needs access to a service that your organization
has not subscribed to or enabled.

Cause: Required Microsoft Graph API permissions haven’t been added to the application.

Solution:

  1. Go to Azure Portal → Azure Active Directory → App registrations
  2. Select your application → API permissions
  3. Click + Add a permissionMicrosoft Graph
  4. Select Application permissions (for service/daemon apps) or Delegated permissions (for user context)

Required permissions for M365 Data Exporter:

  • Mail.Read or Mail.ReadWrite
  • Chat.Read (for Teams)
  • Files.Read.All (for SharePoint/OneDrive)
  • Calendars.Read
  • User.Read.All
  1. Click Grant admin consent for [Your Organization]

AADSTS70011: Invalid Scope

Error Message:

AADSTS70011: The provided value for the input parameter 'scope' is not valid.

Cause: The requested scope is invalid or not configured.

Solution:

For Microsoft Graph API, use proper scope format:

https://graph.microsoft.com/.default

In your code, verify scope configuration:

const scopes = ['https://graph.microsoft.com/.default'];

For delegated permissions, use specific scopes:

const scopes = [
  'User.Read',
  'Mail.Read',
  'Files.Read.All'
];

AADSTS90002: Tenant Not Found

Error Message:

AADSTS90002: Tenant 'your-tenant-id' not found.

Cause: The tenant ID is incorrect or doesn’t exist.

Solution:

  1. Verify your AZURE_TENANT_ID:

    echo $AZURE_TENANT_ID
  2. Find your correct tenant ID:

    • Go to Azure Portal → Azure Active Directory
    • Copy the Tenant ID from the overview page
  3. Update your .env file:

    AZURE_TENANT_ID=correct-tenant-id-here

Token Issues

Access Token Expired

Symptoms: API requests fail with 401 Unauthorized after working previously.

Solution:

Implement proper token refresh logic:

async function getAccessToken() {
  const tokenCache = getTokenFromCache();
 
  if (tokenCache && !isTokenExpired(tokenCache)) {
    return tokenCache.accessToken;
  }
 
  // Token expired or not found, request new token
  const newToken = await requestNewToken();
  saveTokenToCache(newToken);
  return newToken.accessToken;
}
 
function isTokenExpired(token) {
  const expiresAt = token.expiresOn || token.expires_in;
  return Date.now() >= expiresAt - 300000; // Refresh 5 min before expiry
}

Token Too Large (Header Size Limit)

Symptoms: Authentication fails with “Header too large” error.

Cause: Access token contains too many group claims.

Solution:

  1. Go to Azure Portal → Azure Active Directory → App registrations
  2. Select your application → Token configuration
  3. Remove optional claims that aren’t needed
  4. Use group IDs instead of group names in tokens
  5. Alternatively, query groups via Microsoft Graph API instead of including in token

Configuration Issues

Missing Environment Variables

Symptoms: Application crashes on startup with “undefined” errors.

Solution:

Verify all required environment variables are set:

# Required for Azure AD authentication
AZURE_TENANT_ID=your-tenant-id
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
 
# Required for NextAuth.js (Mission Lens web app)
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-random-secret-here
 
# Optional but recommended
NODE_ENV=development

Generate NEXTAUTH_SECRET:

openssl rand -base64 32

Certificate Authentication Issues

For production deployments using certificate authentication:

Error: Unable to load certificate

Solution:

  1. Verify certificate format (PFX/P12 for private key + cert, or separate PEM files)

  2. For PFX/P12:

    const cert = fs.readFileSync('/path/to/certificate.pfx');
    const thumbprint = 'your-cert-thumbprint';
  3. For PEM files:

    const privateKey = fs.readFileSync('/path/to/private-key.pem', 'utf8');
    const certificate = fs.readFileSync('/path/to/certificate.pem', 'utf8');
  4. Upload certificate to Azure AD:

    • Azure Portal → App registrations → Your app → Certificates & secrets
    • Upload the public key (.cer or .pem)

Debugging Authentication

Enable Detailed Logging

For NextAuth.js:

// pages/api/auth/[...nextauth].ts
export default NextAuth({
  debug: true, // Enable debug logging
  logger: {
    error(code, metadata) {
      console.error(code, metadata);
    },
    warn(code) {
      console.warn(code);
    },
    debug(code, metadata) {
      console.debug(code, metadata);
    },
  },
  // ... rest of config
});

For M365 Exporter (Go):

./m365-exporter --log-level debug --type email

Inspect Tokens

Use jwt.ms to decode and inspect JWT tokens:

  1. Copy your access token
  2. Paste it into jwt.ms
  3. Verify:
    • aud (audience): Should be https://graph.microsoft.com
    • scp or roles: Check granted permissions
    • exp (expiration): Ensure token isn’t expired
    • tid (tenant ID): Verify correct tenant

Test Microsoft Graph API Access

Test API access directly with curl:

# Get access token
TOKEN="your-access-token-here"
 
# Test user endpoint
curl -H "Authorization: Bearer $TOKEN" \
  https://graph.microsoft.com/v1.0/me
 
# Test mail endpoint
curl -H "Authorization: Bearer $TOKEN" \
  https://graph.microsoft.com/v1.0/me/messages

If these work but your app doesn’t, the issue is in your application code, not Azure AD.


Best Practices

  1. Secure Credential Storage

    • Use Azure Key Vault for production secrets
    • Never commit credentials to Git
    • Use managed identities when running in Azure
  2. Token Management

    • Implement token caching
    • Refresh tokens before expiration
    • Handle token refresh failures gracefully
  3. Error Handling

    • Log detailed error information (but not tokens!)
    • Implement retry logic for transient failures
    • Provide user-friendly error messages
  4. Security

    • Rotate client secrets every 6 months
    • Use certificate authentication for production
    • Require admin consent for all application permissions
    • Monitor for suspicious authentication patterns
  5. Testing

    • Test authentication in multiple environments
    • Verify permissions are correctly configured
    • Test token refresh logic
    • Simulate authentication failures

Additional Resources


Last updated: January 2025