AADSTS700016: App Not Found in Directory Tenant
Fix AADSTS700016 by signing into the right tenant: verify the directory, add the service principal, and configure consent..
20+ years shipping production backend systems. Lessons pulled from things that broke in production.
- ✓An Azure subscription with access to a Microsoft Entra tenant
- ✓Azure CLI installed with az login completed
- ✓Basic familiarity with OAuth2 sign-in flows
- AADSTS700016 means your app's client ID isn't registered in the tenant that handled the sign-in, so Azure stops before checking secrets
- You're likely aimed at the wrong directory: run
az account showand confirm the tenant ID matches the app registration - An app registration alone isn't enough — each sign-in tenant also needs an enterprise app (service principal)
- For multi-tenant SaaS, set signInAudience to AzureADMultipleOrgs and complete admin consent in each customer tenant
Think of each company Microsoft directory as a separate apartment building with its own front desk. Your app is a visitor with a badge number (the client ID). AADSTS700016 means the visitor arrived at the wrong building: the desk has no record of that badge, so they are turned away. Send them to the right building, register them at that desk (the enterprise app), or issue a multi-building pass (multi-tenant setup). New keys will not help when the building never heard of them.
It's 10 AM on launch day and your first enterprise trial customer can't sign in. They enter their work email, get bounced to Microsoft, and land on a stark error page: AADSTS700016, application not found in the directory. Your team reads it as a credentials problem and burns two hours rotating secrets that were never broken. The customer starts doubting the product before they've seen a single screen of it.
This error is one of the most misread in the Microsoft identity platform. It doesn't mean your code is wrong or your password expired. It means Azure looked for your app's client ID inside a specific tenant directory and found nothing. The app either lives in a different tenant, was never provisioned there as an enterprise app, or was registered as single-tenant while an outsider tried to use it.
The stakes are real because this error almost always appears at the worst moment: customer onboarding, a tenant migration, or the first login after a merger. Every failed attempt erodes trust, and the fix sits with identity configuration that developers rarely touch.
This guide walks you through the three checks that resolve nearly every case: confirming the tenant, confirming the service principal, and confirming the app's audience. You'll get exact CLI commands, a real incident story, and a setup that stops this error from ever paging you again.
What AADSTS700016 Actually Means (and What It Does Not)
AADSTS700016 is Microsoft Entra's way of saying: I looked for this application in the directory that received the request, and it isn't there. The full text reads application with identifier was not found in the directory, followed by the tenant name. Every part of that sentence matters. The identifier is your client ID (app ID). The directory is the specific tenant that handled the sign-in, not some global registry. Not found means exactly that — no app object, no service principal, nothing matching that ID where Azure looked.
What the error doesn't mean is just as important. It doesn't mean the user's password is wrong. It doesn't mean your client secret expired. It doesn't mean your code has a bug in token handling. All of those checks happen later in the pipeline, and Azure never reaches them when the app itself is unknown. Teams routinely waste hours rotating secrets because secret problems feel familiar, while tenant problems feel exotic. Train yourself to read 700016 as a directory problem, not a credential problem.
The error also tells you which tenant answered the request, right in the message text. That tenant name is your first clue. Compare it against the tenant where your app registration lives (visible in the portal's overview blade or via az ad app show). If they differ, you've likely found the whole story: the login flow pointed at a directory that never heard of your app. Common culprits include hardcoding the wrong tenant ID in the authority URL, using common when you meant a specific tenant, or testing with a personal account against a work-only app.
Wrong Tenant, Wrong Directory: Confirming Where You Signed In
The authority URL in your auth configuration decides which tenant handles the login, and getting it wrong is the top cause of AADSTS700016. An authority like https://login.microsoftonline.com/common lets users from any tenant sign in, which is convenient but hides exactly which directory answered. A tenant-specific authority like https://login.microsoftonline.com/aaaabbbb-cccc-tenant-id pins the login to one directory. If that ID is stale — copied from the wrong subscription, left over from a deleted directory, or swapped between staging and production — every login fails with 700016 even though your app registration is perfectly healthy.
Start every investigation by printing the effective tenant on both sides. On the CLI side, az account show --query tenantId reveals which directory your session targets, and az account list shows every directory your account can reach. On the app side, open the registration's overview blade or run the Graph query in the snippet below. If those two tenant IDs don't match, stop debugging code — fix the authority string in your config, environment variable, or appsettings file first.
Directory switching adds another wrinkle. A single Microsoft account can belong to several tenants, and the portal header shows only the current one. Developers often create the registration in tenant A, then run the CLI or open the enterprise-apps blade while switched to tenant B, and conclude the app doesn't exist. It does exist — they're just looking at the wrong building's front desk. Get in the habit of echoing the tenant ID at the top of every debug session so the whole team sees the same directory.
App Registration vs Enterprise App: the Missing Service Principal
Azure's identity model splits every app into two objects, and AADSTS700016 lives in the gap between them. The app object lives in exactly one tenant — the home tenant where someone clicked New registration. The service principal (shown in the portal as an enterprise app) is the local instance inside each tenant where people actually sign in. Your home tenant gets one automatically; every other tenant needs its own, created the first time an admin consents or runs the creation command. Without that local instance, Azure has nowhere to attach permissions, consent grants, or conditional access — so it rejects the login outright.
This is why the classic symptom pattern exists: the developer who created the registration can sign in, but nobody else can. The developer's account lives in the home tenant where the service principal exists. Everyone else authenticates from a tenant with no record of the app. The error message doesn't explain any of this; it just says not found, which sends teams hunting for typos in the client ID.
The fix is mechanical. List service principals in the failing tenant with the filter query below. If it's empty, create the service principal and grant consent. For multi-tenant SaaS this happens once per customer tenant during onboarding — automate it rather than treating it as a one-off favor. And remember that deleting an enterprise app revokes everyone's access in that tenant instantly, which makes it both a useful kill-switch and a dangerous button to click during cleanup.
Multi-Tenant Setup: signInAudience and Admin Consent Done Right
If your product serves more than one company, the app must be multi-tenant — and that means two settings have to agree. First, signInAudience in the app manifest must be AzureADMultipleOrgs (or AzureADandPersonalMicrosoftAccount for consumer scenarios). The default AzureADMyOrg restricts sign-in to the home tenant only, which produces AADSTS700016 for every external user no matter how perfect the rest of the setup is. Second, each customer tenant needs its service principal plus an admin consent grant, because most enterprise tenants disable user self-consent.
The consent flow is where trials go to die quietly. Your app redirects the user to Microsoft, Microsoft notices the tenant hasn't approved the requested permissions, and the login fails. The remedy is the admin consent endpoint: https://login.microsoftonline.com/customer-tenant-id/adminconsent?client_id=your-app-id, opened by someone with admin rights in the customer tenant. Approving it creates the service principal and records the grants in one step. Send this link to the customer's IT contact before kickoff day, not after the failure.
Verify the audience value in automation, not by memory. The snippet below shows how to read and set it from the CLI. Add that read to your deployment checks so a well-meaning portal edit can't silently flip a SaaS app back to single-tenant. Also decide your personal-account policy deliberately: allowing personal Microsoft accounts widens the door to account types you may not want in an enterprise product.
Diagnosing With Sign-In Logs and Audit Trails in Production
When the basics look right but logins still fail, the sign-in logs tell the truth. Microsoft Entra records every authentication attempt — successes, failures, error codes, tenant IDs, conditional-access results — in the sign-in log stream. Filter by your app's client ID around the failure timestamp and you'll see exactly which tenant handled the request, which error code Azure returned, and whether a policy interfered. This beats guessing from the app side, because your app never sees the requests that die at Microsoft's endpoint.
In production, export these logs instead of clicking through the portal. Stream sign-in and audit logs to Log Analytics with a diagnostic setting, then query for error 700016 grouped by tenant and app. A sudden spike from a new tenant name means someone new tried to onboard (or an attacker is spraying client IDs). A steady trickle from a known tenant means a config drifted — often a redirect URI or a rotated certificate that broke a downstream step after the directory lookup succeeded.
Keep the retention window in mind: interactive sign-in logs age out after 30 days by default, so export anything you'll need for a postmortem. Correlate each log row with your app's own callback logs by timestamp and state parameter. If Microsoft logged a failure and your app logged nothing, the request died before redirect — a directory problem. If both sides logged something, you're past 700016 territory and into token or consent errors, which is genuine progress.
Hardening Auth Config So This Never Pages You Again
Once the immediate fire is out, harden the setup so this class of error can't recur silently. Store the tenant ID next to the client ID in every environment's configuration and validate the pair at application startup: if the authority tenant doesn't match the expected registration tenant, fail fast with a message naming both values. A loud startup crash beats a quiet trickle of failed customer logins every time.
Separate your registrations by environment. A single app registration shared across dev, staging, and production guarantees eventual cross-wiring, because redirect URIs and tenant IDs leak between slots. One registration per environment costs nothing and lets you grant consent, rotate secrets, and test tenancy changes without touching production. Name them unambiguously — myapp-prod, myapp-staging — so nobody picks the wrong client ID from a dropdown at midnight.
Finally, put identity checks in the pipeline. Assert signInAudience equals the expected value, assert a service principal exists in each target tenant, and assert the admin consent grants are present. Run these checks on every deploy and on a nightly schedule, because portal edits and customer IT changes drift outside your release process. Identity configuration is production infrastructure — review it, test it, and monitor it like everything else you'd get paged for.
The Trial-Day Login Failure That Was Never a Secret Problem
- Don't let developers debug identity errors by rotating secrets first. AADSTS700016 fires before secrets are even checked, so every rotation is wasted time that burns customer trust during onboarding.
- Single-tenant is the wrong default for any SaaS product. If more than one company will ever sign in, ship multi-tenant from day one — converting later means re-testing every auth flow under deadline pressure.
- Make admin consent a visible onboarding step with a link, an owner, and a verification check. Silent consent failures in locked-down tenants look exactly like broken software to the customer.
az account show --query "{tenant:tenantId, sub:name}" -o table to see the tenant your session uses. Then run az account list -o table to list every directory you can reach. If the tenant in your app's authority URL isn't the one holding the registration, you've found the bug — fix the authority or switch directories.az ad app show --id <APP_CLIENT_ID> --query "{appId:appId, audience:signInAudience}" -o json. If the command fails, the client ID is wrong or you lack Graph permissions. If signInAudience is AzureADMyOrg, the app is single-tenant and every outside account will keep failing until you change the audience.az ad sp list --filter "appId eq '<APP_CLIENT_ID>'" --query "[].{name:displayName}" -o table inside the failing tenant. Empty output means no enterprise app exists there. Create it with az ad sp create --id <APP_CLIENT_ID>, then retry sign-in before changing anything else.common endpoint hides which tenant handled the requestcommon while debugging and switch to https://login.microsoftonline.com/<TENANT_ID> with the explicit tenant. Reproduce the login, then query sign-in logs: az rest --method get --url "https://graph.microsoft.com/v1.0/auditLogs/signIns?$filter=appId eq '<APP_CLIENT_ID>'". The log row shows the exact tenant and error the app hit.https://login.microsoftonline.com/<TENANT_ID>/adminconsent?client_id=<APP_CLIENT_ID> and approve the permissions. Then verify with az ad sp show --id <OBJECT_ID> --query "oauth2PermissionGrants" or the enterprise app's permissions blade. Retry sign-in only after the grants are visible.| File | Command / Code | Purpose |
|---|---|---|
| check-tenant.sh | az account show --query "{tenant:tenantId, subscription:name}" -o table | Wrong Tenant, Wrong Directory |
| check-service-principal.sh | az ad sp list --filter "appId eq '<APP_CLIENT_ID>'" --query "[].{name:displayNam... | App Registration vs Enterprise App |
| set-multitenant-audience.sh | az ad app show --id <APP_CLIENT_ID> --query signInAudience -o tsv | Multi-Tenant Setup |
| query-signin-logs.sh | az rest --method get --url "https://graph.microsoft.com/v1.0/auditLogs/signIns?$... | Diagnosing With Sign-In Logs and Audit Trails in Production |
Key takeaways
az account show and az ad sp list before touching codeCommon mistakes to avoid
5 patternsAssuming the client secret is wrong when the tenant is wrong
az account show --query tenantId -o tsv and compare it with the tenant where the app registration lives. If they differ, sign in against the right tenant or switch directories in the portal before changing any code.Creating the app registration but never creating the service principal
az ad sp create --id <APP_CLIENT_ID>. Then confirm with az ad sp list --filter "appId eq '<APP_CLIENT_ID>'". No service principal means no sign-in, every time.Leaving a SaaS app as single-tenant while selling to other tenants
az ad app update --id <ID> --sign-in-audience AzureADMultipleOrgs. Then complete admin consent in each customer tenant with the /adminconsent endpoint.Registering a redirect URI that doesn't match the running app
Skipping admin consent and hoping users can consent themselves
https://login.microsoftonline.com/<TENANT_ID>/adminconsent?client_id=<APP_CLIENT_ID>, then verify the enterprise app shows the granted permissions. Document consent as a required onboarding step, not an optional one.Interview Questions on This Topic
What does AADSTS700016 mean, and what are its three most common causes?
Frequently Asked Questions
20+ years shipping production backend systems. Lessons pulled from things that broke in production.
That's Azure. Mark it forged?
6 min read · try the examples if you haven't