Entra App Provisioning: What It Does, How to Set It Up, and Common Errors Fixed
Why Entra App Provisioning Is Confusing , And Why It Breaks
I've seen this exact situation play out on dozens of enterprise tenants: an IT admin spends three days configuring Microsoft Entra App Provisioning, flips the switch to "On," and then stares at a Provisioning tab that stubbornly reads "No provisioning has been detected yet." No error. No progress. Just silence. And meanwhile, new hires are sitting at their desks waiting for accounts that will never appear.
Entra App Provisioning , Microsoft's identity lifecycle automation engine inside Microsoft Entra ID, is genuinely powerful. When it works, it automatically creates accounts for new employees across every connected app the moment they land in your directory. It deprovisions access when someone leaves. It keeps display names, job titles, and department fields synchronized across Salesforce, ServiceNow, Workday, and hundreds of other SaaS apps without anyone touching a CSV file. But when it doesn't work, the error messages are almost deliberately cryptic.
The confusion usually starts with one of three things. First, people don't understand the difference between manual and automatic provisioning modes, and they pick the wrong one, or they're trying to automate an app that simply doesn't have a Microsoft Entra provisioning connector yet. Second, the SCIM endpoint authentication is misconfigured: the OAuth 2.0 bearer token either isn't present, is expired, or was issued by the wrong authority. Third, and most insidiously, the provisioning scope filter is set wrong, so the service runs fine but quietly skips every single user you actually want it to provision.
Then there are the certificate issues. If you're running a custom SCIM endpoint built on ASP.NET Core, the .NET development certificate works fine locally, but the moment you deploy, requests start failing with SSL handshake errors because your endpoint doesn't trust the CA chain that Microsoft Entra ID's provisioning service uses to make outbound calls. That list includes DigiCert, GlobalSign, Comodo, VeriSign, GeoTrust, CyberTrust, Go Daddy, WoSign, and DST Root CA X3. Miss one, and provisioning silently dies.
What makes all of this genuinely frustrating is that Microsoft's error messages inside the Provisioning Logs blade rarely point you to the actual root cause. You'll see generic entries like "EntryImportFailed" or "ExportFailed" without enough context to know whether the problem is your token, your endpoint, your attribute mappings, or your network.
This guide cuts through all of that. We'll cover what Entra App Provisioning actually does under the hood, how to configure it step by step the right way the first time, and, most importantly, how to diagnose and fix the specific errors that stop it cold. Browse all Microsoft fix guides →
The Quick Fix, Try This First
If your Entra App Provisioning is already configured but users aren't being provisioned, the fastest fix that resolves the majority of cases is forcing a provisioning cycle restart combined with a scope filter review. Here's exactly what to do:
Go to Microsoft Entra Admin Center → Applications → Enterprise Applications → select your app → Provisioning. If the current status is "On," click Stop and wait for the status to change to "Off." This typically takes 30–60 seconds.
Before you restart, click Edit Provisioning and expand the Settings section. Check the Scope field. If it reads "Sync all users and groups," that's fine. If it reads "Sync only assigned users and groups", which is the default for most gallery apps, then go to the Users and Groups tab and confirm that at least one user or group has actually been assigned to this application. This is the single most common reason provisioning appears to do nothing: the scope is set to assigned users, but no users have been assigned.
If you need to add assignments, click Add user/group, select the accounts you want provisioned, and click Assign. Then go back to Provisioning, click Start, and wait. The initial provisioning cycle, called a full cycle, can take anywhere from 20 minutes to several hours depending on how many users are in scope. Incremental cycles after that run roughly every 40 minutes.
If provisioning still doesn't move after 30 minutes, open Provisioning Logs (the link is right on the Provisioning overview page). Filter by Status = "Failure" and look at the Error column. The specific error code there is your diagnostic clue and will map to one of the step-by-step fixes below.
Before anything else, confirm that your target application actually supports automatic Microsoft Entra ID provisioning. This sounds obvious, but it's a step a lot of people skip, and it leads to hours of frustration configuring something that will never work automatically.
In the Microsoft Entra Admin Center, navigate to Applications → Enterprise Applications → find your app → click Provisioning. Under Provisioning Mode, you'll see one of two options in the dropdown: Automatic or Manual.
If only Manual is available, that means no pre-built Microsoft Entra provisioning connector exists for this application yet. Your options in that scenario are to build a custom SCIM endpoint that the provisioning service can talk to, use one of the non-SCIM connector types (LDAP, SQL, flat-file PowerShell, REST/SOAP Web Services, or a custom ECMA connector), or provision users manually through the app's own admin portal. You cannot force automatic provisioning onto an app that only lists Manual mode.
If Automatic is available and you've selected it, the page will expand to show Admin Credentials, Mappings, and Settings sections. This confirms a provisioning connector exists. For first-party gallery apps like Slack, Snowflake, or Azure Databricks, Microsoft maintains these connectors and they use SCIM under the hood, you don't need to build anything yourself.
For custom apps you've built internally, you'll need to implement a SCIM-compliant endpoint. SCIM, the System for Cross-domain Identity Management specification, gives apps a standardized user schema and REST API structure so the provisioning service knows exactly which endpoints to call and what JSON payloads to send. If you see "Automatic" available but provisioning still fails, continue to Step 2 to validate your credentials and endpoint connectivity.
This is the step where most Entra App Provisioning setups fall apart. The provisioning service needs a way to authenticate to your target application's SCIM endpoint, and it does this using OAuth 2.0 bearer tokens. There are two distinct paths here, and you need to know which one your app expects.
Path A, Microsoft Entra-issued bearer token: If you leave the Secret Token field blank, the provisioning service will automatically attach an OAuth bearer token issued by Microsoft Entra ID itself with every outbound request. Your SCIM endpoint then validates this token. To verify it's legitimate, your endpoint should check the iss claim in the JWT. It will look like this:
"iss": "https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/"
The base address https://sts.windows.net identifies Microsoft Entra ID as the issuer. The GUID segment after it is your specific tenant ID. The audience (aud) claim for custom apps will be 8adf8e6e-67b2-4cf2-a259-e3dc5476c621. Your application must be configured to accept tokens with exactly that audience value or validation will fail and every provisioning request will be rejected with HTTP 401.
Path B, Long-lived bearer token (non-Entra issuer): If your SCIM endpoint uses a token issued by a different authorization server, your own auth service, Okta, or any other OAuth provider, paste that token into the Secret Token field. The provisioning service will send it as-is on every request. Be aware: these tokens can expire. When they do, provisioning stops dead. I've seen orgs go weeks without noticing because the Provisioning status blade still shows "Active" until the next cycle actually fails.
After entering credentials, click Test Connection. A green "The supplied credentials are authorized to enable provisioning" message means endpoint reachability and token validation both passed. If you get a red error, check that your SCIM endpoint URL ends without a trailing slash and that your firewall allows inbound connections from Microsoft Entra's IP ranges.
Attribute mappings are what tell the provisioning service which fields from Microsoft Entra ID (the source) should flow to which fields in your target application. Getting these wrong means users either don't get created at all or get created with blank or incorrect data, neither of which is obvious until someone complains that their display name is missing or their email address is wrong in the app.
In the Provisioning configuration, under Mappings, you'll see at minimum a Provision Microsoft Entra ID Users link and often a Provision Microsoft Entra ID Groups link. Click the user mapping first.
You'll see a table of source attribute → target attribute pairs. The ones marked Required must resolve to a non-null value for every user in scope, or the provisioning entry will fail with an "AttributeValidationFailed" error in your logs. Pay particular attention to userName, in most SCIM implementations this maps to the user's userPrincipalName in Entra ID, and if your UPNs contain characters the target app doesn't accept (like # symbols or routing suffixes), you'll see consistent failures for a specific subset of users.
You can use expression-based mappings to transform data in transit. For example, to strip a domain suffix from a UPN before sending it as the username:
Extract([userPrincipalName], , "@", )
The provisioning engine evaluates these expressions at sync time and sends the transformed value. Test any new expression using Provision on Demand against a specific user, the output panel shows you exactly what value the expression resolved to before the request was sent, which saves enormous debugging time.
If you're provisioning to a brownfield application, meaning users already exist in the target system, check the Matching column in your mappings. The attribute used for matching determines how Entra decides whether to create a new user or update an existing one. Misconfiguring this in a brownfield scenario leads to duplicate accounts rather than matched updates.
Scope filters are powerful but easy to misconfigure in ways that produce zero output with zero error messages. The provisioning service interprets a scoped-out user as "not applicable" rather than "failed," so that user won't appear in your Provisioning Logs at all, you'll just wonder why they were never created.
There are two layers of scope control. The first is the Scope setting under Settings: "Sync all users and groups" vs. "Sync only assigned users and groups." For most production deployments, "Sync only assigned users and groups" is the right choice, it gives you explicit control over who gets provisioned. For that setting to do anything, users or groups must be assigned to the application under Users and Groups.
The second layer is Scoping Filters inside your attribute mappings. These let you add conditions, for example, only provision users where department equals "Engineering" or where accountEnabled is True. To view and edit these, click into your Provision Users mapping, then click Add Scoping Filter. The filter is evaluated against the source (Entra ID) attributes before the provisioning engine decides whether to act on a user.
A common gotcha: if you add a scoping filter that references an attribute your Entra ID users don't actually have populated, like department for users who were imported from an old system without that field, those users silently fall out of scope. Check your filter conditions against real user data by navigating to Microsoft Entra ID → Users → select a user → Properties and verify the attributes you're filtering on are actually populated.
Once scoping is correct, confirm assignments by clicking the Users and Groups tab on your enterprise app. If the list is empty and your scope is set to "Sync only assigned users," provisioning will run and do absolutely nothing. Add your pilot users or a test group here, then trigger a manual cycle using Provision on Demand to validate end to end before enabling full automatic provisioning.
Once provisioning is running, the Provisioning Logs blade is your primary diagnostic tool. Get comfortable with it, it tells you far more than the summary status view. Navigate to Microsoft Entra Admin Center → Applications → Enterprise Applications → your app → Provisioning Logs.
Each log entry shows a User, Action (Create / Update / Delete), Status (Success / Failure / Skipped), and a Reason field. Click any row to expand it into a full detail panel that shows the exact request sent to your SCIM endpoint, the response received, and the specific attribute that caused failure if the issue was data-related.
The most common failure statuses you'll encounter:
- EntryImportFailed, the provisioning service couldn't read the source user from Entra ID. Usually a permissions issue with the service principal.
- SchemaAttributeNotFound, your attribute mapping references a target attribute that doesn't exist in your SCIM schema. Check your endpoint's schema response at
/scim/v2/Schemas. - AzureDirectoryB2BManagementPolicyCheckFailure, a guest user was in scope but B2B policy blocked provisioning. Either exclude guest accounts via a scope filter or adjust your cross-tenant policy.
- InvalidSoftMatch, during brownfield matching, the service found multiple existing users that matched the anchor attribute. You have duplicate accounts in the target system that need to be resolved manually.
Beyond logs, Entra App Provisioning supports email alerts for critical events and integration with Log Analytics for custom alert rules. To enable email notifications, go to Provisioning → Edit Provisioning → Settings → Send an email notification when a failure occurs and enter a distribution list. For Log Analytics integration, connect your Entra audit logs to a Log Analytics workspace via Diagnostic Settings in the Microsoft Entra ID portal, then write KQL queries against the AADProvisioningLogs table to alert on patterns like sustained failure rates or specific error codes. This is especially useful in enterprise environments where a provisioning failure at 2 AM needs to wake someone up before the user's first day.
Advanced Troubleshooting: SCIM Endpoint Auth, Certificates, and Enterprise Scenarios
If you've built a custom SCIM endpoint and are seeing authentication failures that aren't explained by the steps above, the problem is most likely in how your ASP.NET Core application validates the incoming JWT tokens from the Entra provisioning service.
The standard implementation uses the Microsoft.AspNetCore.Authentication.JwtBearer NuGet package. In your ConfigureServices method, you need to set the Authority and Audience to exactly match what the provisioning service sends:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.Authority = "https://sts.windows.net/YOUR-TENANT-ID-HERE/";
options.Audience = "8adf8e6e-67b2-4cf2-a259-e3dc5476c621";
});
Replace YOUR-TENANT-ID-HERE with your actual tenant GUID. The Audience value 8adf8e6e-67b2-4cf2-a259-e3dc5476c621 is the fixed Application ID for all custom apps in the gallery, this is not your app's specific registration ID. And make sure app.UseAuthentication() and app.UseAuthorization() are both called in your Configure method, in that order. Reversing them causes silent auth failures that are extremely confusing to debug.
For local development, the .NET Core SDK provides a self-signed HTTPS development certificate on https://localhost:5001 (or https://localhost:44359 if you're using IIS Express). The sample code handles this by using ASP.NET Core environments, in Development mode, it switches to a self-signed token validation path rather than requiring a proper Entra-issued JWT. In production, you must switch to the full JwtBearer validation shown above.
Certificate trust in production is a common silent killer. The provisioning service makes outbound HTTPS calls to your SCIM endpoint. If your endpoint's TLS certificate isn't issued by one of the trusted CAs that the provisioning service recognizes, specifically Comodo, CyberTrust, DigiCert, GeoTrust, GlobalSign, Go Daddy, VeriSign, WoSign, or DST Root CA X3, every provisioning request will fail with a connection error before it even gets to your authentication logic. Use a certificate from one of those CAs (Let's Encrypt chains to DST Root CA X3 / ISRG Root X1 and generally works fine; DigiCert is the safest enterprise choice).
Domain-joined and hybrid scenarios add another layer. If your org syncs identities from on-premises Active Directory to Entra ID via Microsoft Entra Connect, provisioning runs against the cloud-side attributes, but some attributes like extensionAttribute1 through extensionAttribute15 may not be synced by default. If your attribute mappings reference those extension attributes and they're blank for every user, you'll get consistent empty-field failures. Check your Entra Connect sync rules and enable the attribute sync if needed.
For LDAP and SQL connector types in hybrid environments, the provisioning agent must be installed on a server with line-of-sight to your on-premises directory. Check Windows Event Viewer on that agent host under Applications and Services Logs → Microsoft → AzureADConnect for provisioning agent–specific errors. Event ID 1000 indicates normal operation; Event IDs in the 1500–1599 range typically indicate connectivity or credential failures with the on-premises target.