You assigned Microsoft 365 E3 to a security group, added 300 users, and walked away. A week later the help desk is on fire: forty people have no Exchange mailbox, a dozen can’t open Teams, one VIP is missing Power BI — even though “everyone in that group has E3.” Nothing changed. Except something always did: a user moved to a group that also grants a Teams plan, two licenses now fight over the same service, and Entra silently left those accounts half-provisioned. This is the most common licensing incident in Microsoft Entra ID, and it is maddening because the group shows “licensed” in green while individual services quietly fail.
Group-based licensing (GBL) lets you assign a license — a SKU like ENTERPRISEPACK (Microsoft 365 E3) — to an Entra group instead of one user at a time. Members inherit it; everyone you add or remove is provisioned or stripped automatically. That is the right way to license at scale, but it puts a processing layer between “I assigned it” and “the user actually has it,” and that layer fails in specific, diagnosable ways: a user with no usage location, two groups granting mutually exclusive service plans, a tenant that ran out of licenses, or license drift where a direct and a group assignment disagree. The error never says “your group is fine but user X is broken” — it shows a generic “licenses couldn’t be assigned” and leaves you to find which user, which service, and why.
This is the diagnostic playbook. We treat these not as one bug but as a few failure classes, each confirmed with an exact portal path or a Microsoft Graph PowerShell one-liner, each with a precise fix. You will learn to read a group’s licensing-error state, find the specific users in error, decode the error reasons Entra reports, clear them, and reprocess — then put guardrails up so the next bulk change doesn’t silently strand 40 people again. By the end you stop guessing and know, within a couple of minutes, whether you face a missing usage location, a plan conflict, an out-of-licenses wall, or drift.
What problem this solves
Per-user licensing does not scale. At 5,000 staff, assigning and revoking by hand is slow and error-prone, and every department move means remembering to strip the old license and add the new one. GBL makes membership the source of truth: join the “Sales” group, get the Sales bundle; leave it, lose it. That is exactly what you want — until the provisioning behind it fails, and because it is asynchronous and bulk, it fails quietly and at scale.
What breaks without this knowledge: an admin sees a red banner on the group, panics, and removes the group license entirely — stripping everyone, including the 260 users who were fine. Or assigns the same license directly to the broken users to “fix” it, creating duplicate assignment and drift. Or raises a ticket and waits two days while a sales team has no mailboxes. The real cause is almost always one of four things, each confirmable in under five minutes and fixable without touching the healthy members.
Who hits this: anyone running Microsoft 365 or Entra licensing at real size. It bites hardest right after bulk onboarding (new starters with no usage location), after reorganisations (users land in overlapping groups whose plans conflict), and wherever someone assigns licenses both directly and via a group. The fix is never “remove the group license” — it is “find the users in error, read the reason, clear that reason.”
Before the deep dive, here is the whole field in one table — every failure class, what Entra actually shows you, and where to look first.
| Failure class | What Entra shows | First question to ask | First place to look |
|---|---|---|---|
| Usage location missing | User in error; reason cites a location-dependent service | Did the user ever get a usage location set? | User → Licenses, or UsageLocation in Graph |
| Mutually exclusive plans | “Conflicting service plans” on the user | Is this user in two groups granting the same service? | Group → Licenses → users-in-error blade |
| Out of licenses (SKU full) | “Not enough licenses” on the group | Has consumed reached purchased on this SKU? | Billing → Licenses (consumed vs total) |
| License drift / duplicate | User has the SKU twice; removal blocked | Is the same SKU assigned directly and via a group? | User → Licenses (direct vs inherited tags) |
| Stale state (needs reprocess) | Error persists after you fixed the cause | Did the group reprocess after the fix? | Group → Licenses → Reprocess |
Learning objectives
By the end of this article you can:
- Explain how group-based licensing provisions members, why it is asynchronous, and why the error you see lives on the group but the cause lives on a user.
- Read a group’s licensing error state and find the exact list of users in error, in both the portal and Microsoft Graph PowerShell.
- Diagnose and fix a usage-location-missing failure — the single most common cause — for one user and in bulk.
- Diagnose and resolve mutually exclusive service plan conflicts by disabling the duplicated plan on one assignment.
- Recognise an out-of-licenses (SKU-full) wall, confirm consumed-vs-purchased counts, and free or buy capacity.
- Detect and clean up license drift — a SKU assigned both directly and via a group — without stranding the user.
- Trigger a reprocess so a fixed cause actually clears, and put guardrails (usage-location defaults, no overlapping bundles, group-only assignment) in place to prevent recurrence.
Prerequisites & where this fits
You should know the Entra licensing vocabulary at a beginner level: a SKU (also called a product or licensing plan, e.g. Microsoft 365 E3 = ENTERPRISEPACK) is the thing you buy; it contains many service plans (Exchange Online, Teams, SharePoint, Power BI, Intune…) that you can individually enable or disable. You should be comfortable in the Microsoft Entra admin center / Azure portal, and ideally have the Microsoft Graph PowerShell SDK installed (Install-Module Microsoft.Graph) for the scripted checks — though every check here also has a portal path. You need a role that can manage licenses: License Administrator, User Administrator, or Global Administrator.
This sits in the Identity & governance track and is downstream of the fundamentals. If “tenant,” “group,” and “SKU” are fuzzy, read Microsoft Entra ID Fundamentals: Tenants, Users, Groups & RBAC first. Group-based licensing pairs naturally with Entra ID Dynamic Groups: A Membership-Rule Cookbook That Actually Scales, because a dynamic group is the cleanest way to drive license assignment off attributes — and is also where overlapping-membership conflicts are born. In hybrid tenants, a user’s usageLocation often flows in from on-premises Active Directory through Microsoft Entra Connect Sync Deep Dive: Designing Hybrid Identity with PHS, PTA, and Seamless SSO, which is exactly why “no usage location” surprises people. And the joiner-mover-leaver automation in Automating Joiner-Mover-Leaver with Entra ID Lifecycle Workflows and Custom Extensions is what moves people between groups and therefore triggers most conflicts.
Core concepts
Five mental models make every later diagnosis obvious.
Assignment and provisioning are two different steps. Assigning a SKU to a group records the intent immediately; a background provisioning engine then applies it to each member — mailbox, Teams, SharePoint quota. That second step is asynchronous and per user, so a group can show “assigned” while members are still processing or have failed. The green tick means “the assignment is recorded,” not “every member is provisioned.” Most confusing GBL symptoms come from conflating these two steps.
The error is on the group, but the cause is on a user. When provisioning fails, the group’s Licenses blade shows a banner and counts the users in error. The reason (no usage location, conflicting plans…) is a property of the user. So the move is always: group banner → users in error list → read each user’s reason. Treat the banner as a doorbell, not the diagnosis.
A SKU is a bundle of toggleable service plans. Microsoft 365 E3 isn’t one switch; it’s ~20 service plans you can enable or disable per assignment — and conflicts happen at the plan level, not the SKU level. Two SKUs (a standalone Teams license and an E3) can both contain the Teams plan, and Entra refuses to provision the same plan twice for one user — the “mutually exclusive” conflict. The fix is rarely “remove a license”; it’s “disable the duplicated plan on one of the two assignments.”
Usage location is mandatory. Several services require a user’s usageLocation — a two-letter ISO country code (IN, US, GB) — before they can be provisioned. A user with none cannot receive those plans, so the group license fails for them with a location reason. Cloud-only users often have it blank; hybrid users may or may not inherit it from on-prem AD. This single missing attribute is the number-one GBL failure, and it has nothing to do with the group.
Licenses can be inherited and direct, and they drift. A user can hold the same SKU two ways — inherited from a group and directly assigned. They coexist (still one consumed unit) but cause trouble: you can’t remove an inherited license per-user (you change membership), and a direct assignment can fight a group one. License drift is when the effective state no longer matches the intended group-driven state — usually because someone assigned directly “to fix it fast.” Clean tenants assign one way (via groups) and keep direct assignment for genuine exceptions.
The vocabulary in one table
Pin down every moving part before the deep sections. The glossary repeats these for lookup; this table is the mental model side by side.
| Term | One-line definition | Where it lives | Why it matters to errors |
|---|---|---|---|
| SKU / product | The license you buy (e.g. ENTERPRISEPACK = M365 E3) |
Tenant billing | Runs out → out-of-licenses |
| Service plan | One toggleable service inside a SKU (Exchange, Teams…) | Inside a SKU | Duplicate plan → conflict |
| Group-based licensing | Assigning a SKU to a group; members inherit it | Group → Licenses | The whole feature in question |
| Provisioning engine | The async step that applies the license per user | Platform (background) | Stale errors until reprocess |
| Usage location | The user’s two-letter country code | User property | Missing → top failure cause |
| Inherited license | A license a user gets via group membership | On the user (read-only) | Can’t be removed per-user |
| Direct license | A license assigned straight to the user | On the user | Source of drift/duplicates |
| Users in error | Members whose provisioning failed | Group → Licenses blade | The list you actually act on |
| Reprocess | Re-run provisioning for a group’s members | Group → Licenses | Clears a fixed cause |
| Disabled plan | A service plan switched off on an assignment | Per assignment | The fix for plan conflicts |
The licensing error reference
Before the per-symptom detail, here is the lookup table you scan first. Entra surfaces a small, fixed set of error reasons on a user whose group license failed to provision. These are the strings (and their Microsoft Graph equivalents) you will actually see, what each means, how to confirm it, and the fix. The non-obvious one is MutuallyExclusiveViolation — it sounds like a policy block but is almost always two overlapping bundles.
| Error reason (portal / Graph) | What it means | Likely cause | How to confirm | First fix |
|---|---|---|---|---|
Usage location not allowed / UsageLocationNotAllowed |
A plan can’t be provisioned for the user’s (missing or restricted) location | usageLocation blank, or service unavailable in that country |
User → Licenses shows the reason; check usageLocation in Graph |
Set a valid usageLocation, then reprocess |
Conflicting service plans / MutuallyExclusiveViolation |
The same service plan is granted twice for this user | User is in two groups (or has a direct license) granting the same plan | Users-in-error blade names the conflicting plans | Disable the duplicated plan on one assignment |
Not enough licenses / CountViolation |
The SKU has no free units left to provision this user | Consumed has reached purchased for the SKU | Billing → Licenses consumed vs total | Free up units or buy more, then reprocess |
Other / ProhibitedInUsageLocationViolation |
A plan is legally prohibited in the user’s country | Location is set but the service is blocked there | Reason text names the prohibited plan/country | Disable that plan for those users, or accept it’s unavailable |
| Dependency not enabled (within a SKU) | A plan you enabled requires another plan that’s disabled | You toggled plans and broke a dependency | Compare enabled plans; reason cites the dependency | Re-enable the required dependent plan |
Two reading notes that save the most time:
| Distinction | The trap | How to tell them apart |
|---|---|---|
| Group banner vs user reason | The group banner only counts errors; it never names the cause | Always drill into users in error — the reason is on the user |
| “Assigned” vs “provisioned” | Green on the group ≠ the service works for the member | Check the user’s per-service status, or that the mailbox/Teams actually exists |
Anatomy of a usage-location failure
The one you will hit most. A user has no usageLocation (or one that prohibits a service), so the location-dependent plans in your group’s SKU can’t be provisioned. The group shows N users in error, each naming a location reason.
Confirm it
In the portal: Groups → <your group> → Licenses. The banner reads “X users couldn’t be assigned licenses.” Click it for the users in error list; a usage-location failure names the location or a location-restricted service. To confirm on the user, check the attribute with Microsoft Graph PowerShell:
# Connect once with the scopes you need
Connect-MgGraph -Scopes "User.ReadWrite.All","Organization.Read.All","Group.Read.All"
# Is the user's usage location actually set?
Get-MgUser -UserId "ravi@contoso.com" -Property "displayName,usageLocation,userPrincipalName" |
Select-Object DisplayName, UserPrincipalName, UsageLocation
# UsageLocation empty -> this is your cause
To find every user who is missing a usage location (the bulk version, which is what you usually want after an onboarding):
# All enabled member users with no usage location set
Get-MgUser -All -Filter "accountEnabled eq true and userType eq 'Member'" `
-Property "displayName,userPrincipalName,usageLocation" |
Where-Object { -not $_.UsageLocation } |
Select-Object DisplayName, UserPrincipalName
Fix it
Set a valid two-letter usage location, for one user or in bulk, then let the group reprocess.
# One user
Update-MgUser -UserId "ravi@contoso.com" -UsageLocation "IN"
# Bulk: set every member with no location to IN (adjust to your tenant)
Get-MgUser -All -Filter "accountEnabled eq true and userType eq 'Member'" `
-Property "id,usageLocation" |
Where-Object { -not $_.UsageLocation } |
ForEach-Object { Update-MgUser -UserId $_.Id -UsageLocation "IN" }
The portal equivalent is User → Properties → Settings → Usage location. The lasting fix is to stop it recurring — set a usage location at account creation:
| Where you set usage location | Covers which users | Gotcha |
|---|---|---|
Per user (portal / Update-MgUser) |
The one in error | Manual; doesn’t prevent the next |
| Bulk Graph script (filter + loop) | All current blanks | Re-run after each onboarding wave |
| On-prem AD attribute (hybrid) | All synced users going forward | Must map the right attribute (c) in Entra Connect |
| Onboarding template / IaC (cloud-only) | All new cloud users | Needs a disciplined creation process |
A note on prohibited locations: if the reason is ProhibitedInUsageLocationViolation rather than a missing location, the user has a location but that plan can’t run there legally — the fix is to disable that plan for those users (see the conflict section), not change their country.
Anatomy of a service-plan conflict
The second-most-common failure, and the most misunderstood. Entra refuses to provision the same service plan twice for one user. It happens when two licenses both contain a plan — a standalone Microsoft Teams license and an E3 (which includes Teams), or two overlapping group bundles. The reason reads conflicting service plans / MutuallyExclusiveViolation and blocks the conflicting plan (sometimes the whole assignment).
Confirm it
Groups → <group> → Licenses → users in error names the conflicting plans. To see why, look at every license the user holds and where each comes from:
# What licenses does the user have, and which service plans are enabled vs disabled?
Get-MgUserLicenseDetail -UserId "meera@contoso.com" |
Select-Object SkuPartNumber,
@{n='EnabledPlans'; e={ ($_.ServicePlans | Where-Object ProvisioningStatus -eq 'Success').ServicePlanName -join ', ' }}
If the same plan name (e.g. TEAMS1) appears under two SKUs the user holds, that’s your conflict. To see which assignments are group-inherited versus direct (so you know which one to change), inspect licenseAssignmentStates:
# For each assigned SKU, is it from a group (assignedByGroup populated) or direct (null)?
(Get-MgUser -UserId "meera@contoso.com" -Property "licenseAssignmentStates").AdditionalProperties.licenseAssignmentStates |
ForEach-Object { [pscustomobject]@{ Sku = $_.skuId; FromGroup = $_.assignedByGroup; State = $_.state } }
Fix it
You do not remove a license — you disable the duplicated plan on one of the two assignments so it’s granted exactly once. Decide which assignment wins the plan (usually the richer bundle keeps it; the narrower one disables it), then turn it off there.
In the portal: open the assignment (group → Licenses → the SKU → service plans, or the user’s direct license) and untoggle the duplicated plan. In Graph, add the conflicting plan’s ID to that assignment’s disabledPlans. The idea is one plan, one source. The decision and effect:
| Situation | Which assignment keeps the plan | What you disable | Result |
|---|---|---|---|
| Standalone Teams + E3 group | E3 (the bundle) keeps Teams | Disable Teams on the standalone license (or remove the standalone) | One Teams plan; conflict clears |
| Two overlapping group bundles | The “primary” group keeps the plan | Disable the plan on the secondary group’s assignment | Both groups apply; no double-grant |
| Direct license + group license | The group keeps it (group-only model) | Remove/trim the direct assignment | Drift removed; group is source of truth |
After disabling the plan, the conflict clears on the next reprocess. The real cure is to stop building overlapping bundles — don’t have one group grant standalone Teams and another grant E3 land on the same people. Map bundles so memberships don’t overlap on a shared plan; the conflict you never create is the one you never debug.
Anatomy of an out-of-licenses failure
Blunt: the SKU has no free units left. Entra can’t provision a member because consumed has reached purchased. The group shows users in error with not enough licenses / CountViolation. The most recently added members stay unprovisioned while earlier ones are fine — it fills until it’s full.
Confirm it
Billing → Licenses shows each SKU with assigned/consumed vs total. If consumed equals total for the SKU your group grants, that’s the wall. Via Graph:
# Consumed vs purchased (enabled) units per SKU
Get-MgSubscribedSku |
Select-Object SkuPartNumber,
@{n='Consumed'; e={ $_.ConsumedUnits }},
@{n='Purchased'; e={ $_.PrepaidUnits.Enabled }} |
Format-Table -AutoSize
# Consumed == Purchased -> out of licenses for that SKU
Fix it
Two levers: free units or buy units. Free them by removing the SKU from users or groups that don’t need it — often a stale group still granting it, or users who left a team but not the group. Buy them in Billing → Your products (or via your CSP/EA). Then reprocess so the freed units provision the waiting members.
A subtlety worth internalising: a SKU unit is consumed per user, not per service plan. Disabling unused plans on an assignment makes the entitlement cleaner and more secure but does not return a fractional license — one user with E3 (even with half its plans off) still consumes one E3 unit. So “we’re out of E3” is solved by fewer users on E3 or more units, never by trimming plans.
Anatomy of license drift and duplicate assignment
Drift is the slow one: over time the effective license state stops matching the intended group-driven state. The classic trigger is someone assigning a SKU directly to “fix” a provisioning hiccup, on top of the group that already grants it. Now the user has the SKU twice — inherited and direct. It still consumes one unit, but it creates traps: you can’t strip the inherited copy per-user, the two assignments can carry different disabled plans, and a later cleanup that removes the group license leaves the direct one behind (or vice versa), so access changes unexpectedly.
Confirm it
Look at the user’s assignment states and check whether the same SKU appears both inherited (from a group) and direct:
# Flag SKUs the user holds BOTH directly and via a group (drift / duplicate)
$states = (Get-MgUser -UserId "arjun@contoso.com" -Property "licenseAssignmentStates").AdditionalProperties.licenseAssignmentStates
$states | Group-Object skuId | Where-Object {
($_.Group.assignedByGroup | Where-Object { $_ }) -and # at least one from a group
($_.Group.assignedByGroup | Where-Object { -not $_ }) # and at least one direct
} | ForEach-Object { "DUPLICATE SKU: $($_.Name)" }
In the portal, User → Licenses tags each license as inherited (shows the source group) or directly assigned; the same SKU listed both ways is the duplicate.
Fix it
Pick one source of truth — for most tenants, the group — and remove the direct assignment so the user keeps only the inherited one:
# Remove only the DIRECT assignment of a SKU, leaving the group-inherited one intact
$skuId = (Get-MgSubscribedSku | Where-Object SkuPartNumber -eq "ENTERPRISEPACK").SkuId
Set-MgUserLicense -UserId "arjun@contoso.com" -AddLicenses @() -RemoveLicenses @($skuId)
# This removes the directly-assigned SKU; the group keeps re-applying its inherited copy
You cannot remove a group-inherited license from an individual — by design. If one user genuinely shouldn’t have what the group grants, remove them from the group (or exclude them via a dynamic-group rule), not a per-user override. The drift scenarios and their correct moves:
| Drift scenario | What you see | Correct fix | What NOT to do |
|---|---|---|---|
| SKU direct + inherited | Same SKU twice on the user | Remove the direct one; keep the group | Try to remove the inherited one per-user (blocked) |
| Plans differ between copies | Teams on in group, off direct (or reverse) | Standardise on the group’s plan set | Hand-edit the direct copy and forget the group |
| Group removed, direct left behind | User still has SKU after group change | Remove the leftover direct assignment | Assume removing the group cleaned everything |
| User should be exempt | One member shouldn’t get the bundle | Change membership (remove / dynamic exclude) | Per-user remove of the inherited license |
Reprocessing: making a fixed cause actually clear
The step people forget, then conclude “my fix didn’t work.” After you correct the cause — set the usage location, disable the duplicated plan, free up units — the user’s error doesn’t always clear instantly. Provisioning is asynchronous; the engine re-evaluates on a schedule, but you can force it via Groups → <group> → Licenses → Reprocess, which re-runs provisioning for the members and clears errors whose cause is now resolved.
Things to know: reprocess is safe (it re-applies the intended state; it never strips correctly-licensed users); it acts at the group level (every member is re-evaluated); and if an error persists after reprocess, the cause isn’t actually fixed — re-read the user’s reason. Changing usageLocation or membership also nudges provisioning, but reprocess is the explicit, immediate way.
| Symptom after your fix | What it means | Next move |
|---|---|---|
| Error clears within minutes (no action) | Engine re-evaluated on its own | Nothing — you’re done |
| Error clears after Reprocess | The fix was right; it just needed a kick | Done; consider why it didn’t auto-clear |
| Error persists after Reprocess | The root cause is still present | Re-open the user’s reason; you fixed the wrong thing |
| New users still erroring | A preventive gap (e.g. no default usage location) | Fix the onboarding source, not just the symptom |
Architecture at a glance
Hold this model and every symptom locates itself. Picture three layers, top to bottom. At the top, your tenant SKU inventory — the units you bought per product (E3, E5, standalone Teams). In the middle, the group, to which you assigned one or more SKUs with a chosen set of enabled plans, and which has members (static or dynamic). At the bottom, each user, with a usageLocation and a mix of inherited licenses (from groups) and possibly direct ones.
Between group and users sits the part you can’t see: the provisioning engine. When you assign a SKU to the group, it fans out to every member — checking each user’s usage location, checking no plan is granted twice, and decrementing the SKU’s units by one per user. A failure at any check parks that user in error, while the group shows a count.
Read a failure top-down. Out of licenses is the inventory layer running dry (consumed = purchased). Conflicting plans is the group/membership layer — two assignments overlap on a plan for one user. Usage location missing is the user layer — the bottom check fails. Drift is a mismatch between what the group intends and what the user holds. Every diagnosis is “which layer fails the check, for which user?” — the fix lives at that layer, and reprocess re-runs the whole fan-out afterward. That’s the entire method: localise the failing check to a layer and a user, fix it there, reprocess.
Real-world scenario
Nimbus Logistics, a 1,200-person Indian freight company, runs Microsoft 365 E3 entirely through group-based licensing: a security group GBL-M365-E3 holds the E3 SKU and is populated by a dynamic rule on department. The identity team is two engineers; the tenant has 1,200 E3 units purchased, with about 60 spare. Licensing had “just worked” for a year.
The incident began the Monday after a reorg. Over the weekend HR moved 180 people between departments, and a new GBL-Teams-Premium group (a standalone Teams add-on for the leadership tier) had gone to ~90 managers on Friday. By 09:30 the service desk had 50+ tickets: missing mailboxes for new joiners and managers reporting Teams had “lost” features. The on-call engineer’s first reflex was GBL-M365-E3 — a red banner: “47 users couldn’t be assigned licenses.” The instinct to remove and re-add the group license was, thankfully, overruled.
The breakthrough was drilling into users in error. The 47 split in two. Thirty-one were weekend new-hires from a cloud-only script that never set usageLocation — a usage-location failure, confirmed blank by Get-MgUser. The other sixteen were managers in both GBL-M365-E3 (Teams included) and the new add-on group — MutuallyExclusiveViolation on the Teams plan. Two unrelated causes behind one banner, both surfaced by the reorg.
The fixes were targeted. For the 31: a bulk Update-MgUser -UsageLocation "IN" over the filtered list, then Reprocess — all 31 provisioned in minutes. For the 16: the team let the E3 bundle own Teams and disabled the Teams plan on the GBL-Teams-Premium assignment (the add-on was meant for premium meeting features, mis-scoped to include base Teams). Reprocess cleared the conflict. Total time from “remove the group?” to “all clear”: ~40 minutes, with zero impact to the 1,153 healthy members.
The follow-up mattered more. They defaulted a usage location in the onboarding script (and the on-prem AD c attribute for synced users), re-scoped GBL-Teams-Premium to grant only the add-on plan, and wrote a one-line standard: licenses by group only; direct assignment requires a ticket. The lesson on the wall: “The banner is on the group, but the bug is on a user. Drill in before you touch the group.” The timeline, because the order of moves is the lesson:
| Time | Symptom | Action taken | Effect | What it should have been |
|---|---|---|---|---|
| 09:30 | Banner: 47 users in error | (tickets pile up) | — | Drill into users-in-error first |
| 09:35 | “Just remove the group?” | (proposed, overruled) | Avoided stripping 1,153 users | Never strip the group blind |
| 09:45 | Two populations found | Read each user’s reason | 31 location, 16 plan conflict | This was the breakthrough |
| 09:55 | 31 location failures | Bulk Update-MgUser + Reprocess |
All 31 provisioned | Correct fix |
| 10:05 | 16 plan conflicts | Disable Teams on the add-on assignment + Reprocess | Conflicts clear | Correct fix |
| +1 day | Prevent recurrence | Default usage location; re-scope add-on; group-only policy | No repeat | The real fix is prevention |
Advantages and disadvantages
Group-based licensing is the right model at scale, but the same automation that saves you causes this error class. Weigh it honestly.
| Advantages (why GBL helps you) | Disadvantages (why it bites) |
|---|---|
| Membership is the source of truth — join a group, get the license; no per-user toil | The error is reported on the group but caused on a user — you must drill in to diagnose |
| Provisioning is automatic for adds and removes — no “forgot to revoke” | It’s asynchronous: “assigned” on the group ≠ “provisioned” for every member |
| Pairs with dynamic groups to license off attributes (department, country) | Overlapping group memberships create service-plan conflicts you didn’t intend |
| One change licenses thousands consistently | One wrong change (or removing the group license) strips thousands at once |
| Disabled-plan choices are applied uniformly across the group | A SKU unit is whole-user — trimming plans doesn’t reclaim a license |
| Centralised, auditable assignment instead of scattered per-user grants | Drift appears when anyone also assigns directly “to fix it fast” |
The model is right for any tenant past a few dozen users where membership should drive entitlement and you keep bundles non-overlapping. It bites hardest after bulk onboarding (usage location), reorganisations (overlap conflicts), and where people assign both directly and by group (drift). Every disadvantage is manageable — if you know it exists, drill into users-in-error rather than the group, and assign one way.
Hands-on lab
Reproduce a usage-location failure end to end, see it in the group, fix it, and reprocess — using a single test user and a group, no production impact. You need License Administrator (or higher) and the Microsoft Graph PowerShell SDK. This uses one license unit temporarily; remove it at the end.
Step 1 — Connect and confirm you have a free unit of a SKU.
Connect-MgGraph -Scopes "User.ReadWrite.All","Group.ReadWrite.All","Organization.Read.All","Directory.ReadWrite.All"
Get-MgSubscribedSku | Select-Object SkuPartNumber,
@{n='Consumed';e={$_.ConsumedUnits}}, @{n='Purchased';e={$_.PrepaidUnits.Enabled}} | Format-Table
# Pick a SKU with Consumed < Purchased, e.g. ENTERPRISEPACK. Note its SkuId.
Step 2 — Create a test user with NO usage location (this reproduces the bug).
$pwd = @{ Password = "Lab-$([guid]::NewGuid().Guid.Substring(0,8))!"; ForceChangePasswordNextSignIn = $true }
$u = New-MgUser -DisplayName "GBL Lab User" -AccountEnabled `
-MailNickname "gbl-lab" -UserPrincipalName "gbl-lab@<yourtenant>.onmicrosoft.com" `
-PasswordProfile $pwd
# Deliberately do NOT set -UsageLocation
Step 3 — Create a group, assign the SKU to it, and add the user.
$g = New-MgGroup -DisplayName "GBL-Lab-E3" -MailEnabled:$false `
-MailNickname "gbl-lab-e3" -SecurityEnabled
$sku = (Get-MgSubscribedSku | Where-Object SkuPartNumber -eq "ENTERPRISEPACK").SkuId
Set-MgGroupLicense -GroupId $g.Id -AddLicenses @{ SkuId = $sku } -RemoveLicenses @()
New-MgGroupMember -GroupId $g.Id -DirectoryObjectId $u.Id
Step 4 — Observe the failure. In the portal, Groups → GBL-Lab-E3 → Licenses shows a banner that a user couldn’t be assigned. Confirm via Graph that the user is in error with a location reason:
Start-Sleep -Seconds 30 # give provisioning a moment
(Get-MgUser -UserId $u.Id -Property "licenseAssignmentStates").AdditionalProperties.licenseAssignmentStates |
ForEach-Object { [pscustomobject]@{ Sku=$_.skuId; State=$_.state; Error=$_.error } }
# Expect State = Error, Error mentioning usage location
Step 5 — Fix it: set a usage location, then reprocess.
Update-MgUser -UserId $u.Id -UsageLocation "IN"
In the portal, Groups → GBL-Lab-E3 → Licenses → Reprocess. Wait a minute, then re-check:
Start-Sleep -Seconds 30
(Get-MgUser -UserId $u.Id -Property "licenseAssignmentStates").AdditionalProperties.licenseAssignmentStates |
ForEach-Object { [pscustomobject]@{ Sku=$_.skuId; State=$_.state } }
# Expect State = Active -> provisioned
Validation checklist. You created a real group-based licensing error from nothing but a missing attribute, saw it on the group banner, confirmed the reason on the user, fixed the attribute, and cleared it with reprocess — exactly the production loop. What each step proves:
| Step | What you did | What it proves |
|---|---|---|
| 2 | User without usage location | The attribute, not the group, is the cause |
| 4 | Read user’s error state | The reason lives on the user, not the banner |
| 5 | Set location + Reprocess | The fix + the kick that makes it clear |
Cleanup (free the unit and remove test objects).
Set-MgGroupLicense -GroupId $g.Id -AddLicenses @() -RemoveLicenses @($sku) # release the unit
Remove-MgGroup -GroupId $g.Id
Remove-MgUser -UserId $u.Id
Cost note. Group-based licensing itself is free — it’s a feature of Entra ID P1 (included with Microsoft 365 E3/E5 and many bundles). The only “cost” in this lab is the one license unit consumed for a few minutes, returned at cleanup.
Common mistakes & troubleshooting
This is the playbook — the part you bookmark. First a scannable table you can read mid-incident, then the entries that bite hardest with full confirm-command detail. It spans the basic failures (usage location, out of licenses) and the subtler ones (plan conflicts, drift, reprocess, P1-licensing gaps).
| # | Symptom | Root cause | Confirm (exact cmd / portal path) | Fix |
|---|---|---|---|---|
| 1 | New joiners in a group have no mailbox/Teams; group shows “X users couldn’t be assigned” | Usage location missing on those users | Group → Licenses → users in error (location reason); Get-MgUser -Property usageLocation is blank |
Update-MgUser -UsageLocation "IN"; reprocess |
| 2 | A user’s Teams/feature “disappears”; reason says conflicting plans | Mutually exclusive service plan — same plan from two licenses | Users-in-error names the plans; Get-MgUserLicenseDetail shows the plan under two SKUs |
Disable the duplicated plan on one assignment; reprocess |
| 3 | Most-recently-added members never provision; older ones fine | Out of licenses — SKU consumed = purchased | Billing → Licenses (consumed vs total); Get-MgSubscribedSku |
Reclaim unused units or buy more; reprocess |
| 4 | Same SKU shows twice on a user; can’t remove one copy | Drift / duplicate — SKU assigned direct and via group | User → Licenses (inherited vs direct tags); licenseAssignmentStates grouped by SKU |
Remove the direct assignment; keep the group’s |
| 5 | “Cannot remove license” when trying to unlicense one user | License is group-inherited, not direct | User → Licenses shows the source group | Change membership (remove / dynamic exclude), not the license |
| 6 | You fixed the cause but the error won’t clear | Provisioning is async; group wasn’t reprocessed | Error still on user after the fix | Group → Licenses → Reprocess |
| 7 | Error persists even after Reprocess | The root cause is not actually fixed | Re-read the user’s reason text | Fix the real reason; reprocess again |
| 8 | Removing a group’s license stripped hundreds of users | The group license is the only source; removal cascades | Activity log shows mass license removal | Re-assign at group; never “remove to retry” |
| 9 | A plan you enabled fails with a dependency error | A service plan needs another dependent plan that’s disabled | Reason cites the dependency; compare enabled plans | Re-enable the required dependent plan; reprocess |
| 10 | One SKU “full” but you have spare seats of another | Group grants the wrong/over-rich SKU for that population | Get-MgSubscribedSku shows the full SKU vs spare ones |
Move that population to a SKU with free units |
| 11 | Group assignment silently does nothing for some users | Those users (or the group) lack the prerequisite P1 entitlement, or are unlicensed for GBL | Verify Entra ID P1 coverage; check user types (guests) | Ensure P1 coverage; don’t GBL-license guests this way |
| 12 | Dynamic group: users licensed/stripped unexpectedly | Membership churn from the dynamic rule re-evaluating | Group → Members vs the rule; processing state | Tighten the rule; expect adds/removes to re-license |
| 13 | A few users fail with a location set, plan unavailable | Prohibited in usage location (legal block) | Reason ProhibitedInUsageLocationViolation names plan/country |
Disable that plan for those users; it’s unavailable there |
| 14 | “It works in portal but my script over-removes licenses” | Set-MgUserLicense replaces, and can’t touch inherited |
Compare intended vs licenseAssignmentStates after run |
Only remove direct SKUs by ID; manage inherited via groups |
The expanded reasoning for the entries that bite hardest:
2. A user’s Teams or a feature “disappears”; reason is conflicting service plans. The cause is MutuallyExclusiveViolation — the same plan granted by two licenses (standalone Teams + E3, or two overlapping groups). Confirm: Get-MgUserLicenseDetail shows the same plan name under two SKUs, and licenseAssignmentStates shows which is from a group. Fix: decide which assignment keeps the plan, disable it on the other, then reprocess — and stop building overlapping bundles.
5. “Cannot remove license” when unlicensing one user. The license is group-inherited; by design you can’t strip it per-user. Confirm: User → Licenses shows it came from a group. Fix: change the user’s group membership (remove them, or add a dynamic-rule exclusion). A per-user removal of an inherited license will never work.
6 & 7. The fix didn’t clear, even after Reprocess. Either provisioning hadn’t been reprocessed yet (it’s asynchronous), or — if reprocess didn’t help — the root cause is still present. Confirm: if the error survives a reprocess, re-open the user’s reason; it names what’s still wrong (location blank, plan still duplicated, still out of units). Reprocess is the test that your fix worked — if it persists, you fixed the wrong thing.
8. Removing the group license stripped everyone. The group is the sole source of that license, so removing it from the group cascades to every member. Confirm: the activity log shows a bulk removal from the group change. Fix: re-assign the SKU to the group to re-provision. The lesson: never “remove and re-add” a group license to retry — drill into users-in-error instead.
Best practices
- Assign licenses one way — by group. Reserve direct assignment for ticketed exceptions; one source of truth is the biggest defence against drift.
- Set
usageLocationat account creation. Default it in the cloud onboarding script and map the on-prem AD attribute for synced users, so no account arrives blank. - Keep bundles non-overlapping. Don’t let two groups grant the same plan to the same people — that overlap is the conflict.
- Drill into users-in-error, never the group. The banner is a doorbell; the reason lives on the user.
- Reprocess after every fix, and treat it as a test. If the error survives reprocess, your fix was wrong.
- Watch consumed-vs-purchased per SKU. Alert before a SKU fills so onboarding doesn’t silently strand new starters.
- Use dynamic groups carefully. The cleanest driver and the most common source of accidental overlap — review rules before they touch licensing.
- Never “remove and re-add” a group license to retry. It strips every member. Fix the user-level cause and reprocess.
- Document which group grants which SKU and plans. A simple table beats archaeology six months later.
- Right-size the SKU to the population. If a group is “full,” check whether those users actually need that SKU before buying more.
Security notes
- Least-privilege on license admins. Licensing can enable or disable security-relevant services (Intune, Defender, plans that carry conditional access). Use License Administrator for license tasks, not Global Administrator.
- Disabling a plan is a security control, not just a cost one. Withholding a service from a population is done via the assignment’s disabled plans — get it right, because a conflict-driven mistake can enable a service you meant to withhold.
- Mind data residency via usage location.
usageLocationgoverns where some services are provisioned and what’s legally permitted; a wrong or convenient-but-incorrect default can put data in the wrong jurisdiction. - Don’t license guests through member groups. Guest accounts have different licensing semantics; mixing them into member-licensing groups causes silent failures and unexpected entitlements.
- Audit license changes. Assignment changes appear in the Entra audit logs — a sudden mass strip or a flurry of direct assignments is a signal worth investigating.
Cost & sizing
Group-based licensing is free to use — it ships with Entra ID P1, which is included in Microsoft 365 E3/E5, EMS, and Business Premium, so most tenants already have it. There is no per-assignment charge; the cost is entirely in the SKUs (seats) you consume.
What drives the bill and how it interacts with these errors:
- Seat count is the only real cost. Every member who provisions consumes one whole unit of the SKU. Trimming service plans on an assignment is good hygiene and security, but it does not reclaim a fractional license — a unit is whole-user.
- Over-granting is the silent waste. A group that grants E5 to people who only need E3-level services burns the price difference per user, every month. The “we’re out of licenses” wall is often “we’re over-granting,” not “we need more seats.”
- Reclaim before you buy. Out-of-licenses is frequently solved by removing the SKU from stale groups or users who left a team but not the group — free units you already paid for.
- Right-size the SKU to the population. Map each group to the cheapest SKU that covers its required plans; don’t standardise everyone on the richest bundle for convenience.
Rough figures (list prices vary by region and agreement; treat as ballpark): Microsoft 365 E3 is on the order of ₹3,000–3,500 per user per month, E5 roughly ₹4,500–5,500. The gap across a few hundred mis-assigned users is real money. A quick sizing sanity loop: alert at ~90% consumed per SKU and reclaim or buy ahead; check that E5 users actually use E5-only services (downgrade those who don’t); remove SKUs from stale groups; and map the cheapest-fit SKU per group rather than one rich bundle for all.
Interview & exam questions
1. Why is a GBL error reported on the group but caused on a user? GBL assigns a SKU to a group; members inherit it and are provisioned by an asynchronous engine. The banner only counts failures — the reason (usage location, conflicting plans, out of licenses) is a property of each user, so you drill into users-in-error to find it.
2. A batch of new users in a licensed group have no mailbox. Cause and fix? Usage location missing — location-dependent plans can’t provision without a two-letter usageLocation. Confirm with Get-MgUser -Property usageLocation (blank); fix with Update-MgUser -UsageLocation "IN" and reprocess. Prevent it by defaulting the location at account creation.
3. What does MutuallyExclusiveViolation (conflicting service plans) mean? The same plan is granted to one user by two licenses — e.g. a standalone Teams license and an E3 (which includes Teams), or two overlapping bundles. Entra won’t provision a plan twice. Fix by disabling the duplicated plan on one assignment, not removing a license.
4. Why can’t you remove an inherited license from one user? It’s controlled by membership, by design. To unlicense one person, remove them from the group (or add a dynamic-rule exclusion). Per-user removal works only for directly assigned licenses.
5. Consumed equals purchased and new members won’t provision. What’s happening? Out of licenses (CountViolation) — no free units, so waiting members (usually the most recently added) can’t be allocated one. Confirm in Billing → Licenses or Get-MgSubscribedSku; fix by reclaiming units or buying more, then reprocess.
6. What is license drift and how do you fix a duplicate assignment? Drift is when the effective state diverges from the intended group-driven state — classically a SKU assigned both directly and via a group. It consumes one unit but causes removal/plan inconsistencies. Fix by removing the direct assignment (Set-MgUserLicense -RemoveLicenses) and keeping the inherited one.
7. You fixed the cause but the user is still in error. What did you forget? Reprocess (Group → Licenses → Reprocess) — provisioning is asynchronous. If the error persists after reprocess, the cause isn’t actually fixed; re-read the user’s reason.
8. Does disabling unused plans on an E5 assignment reduce cost? No. A unit is consumed per user regardless of how many plans are enabled. Disabling plans is good hygiene and a security control, but returns no fractional license. Cost falls only with fewer users or a cheaper SKU.
9. Why is removing a group’s license a dangerous “fix”? If the group is the sole source, removing it strips every member — turning a few users-in-error into a tenant-wide outage. Drill into users-in-error and fix the specific cause instead.
10. How do dynamic groups interact with GBL, for better and worse? They license users automatically off attributes (department, country) — the cleanest driver — but risk accidental overlap (a user matching two rules lands in two groups sharing a plan → conflict), and rule re-evaluation churns membership, re-licensing or stripping users. Review rules before they drive licensing.
These map to MS-102 (Microsoft 365 Administrator) — manage users, groups and licenses — and AZ-104 (Azure Administrator) for the Entra ID identity-management objectives. A compact cert mapping:
| Question theme | Primary cert | Objective area |
|---|---|---|
| GBL model, users-in-error, reprocess | MS-102 | Manage licenses in Microsoft 365 |
| Usage location, provisioning | MS-102 | Manage users and licenses |
| Service-plan conflicts, disabled plans | MS-102 | Assign and manage licenses |
| Groups (static/dynamic) driving licensing | AZ-104 / MS-102 | Manage Entra ID groups |
| Roles for license admin (least privilege) | AZ-104 | Manage Entra ID identities & roles |
Quick check
- A group’s Licenses blade says “12 users couldn’t be assigned.” Where do you click next, and where does the actual reason live?
- New cloud-only users in a licensed group have no mailbox. What single attribute do you check first, and what command sets it?
- True or false: disabling the Teams service plan on one of two conflicting assignments is the right way to clear a
MutuallyExclusiveViolation. - You corrected a user’s usage location but their error hasn’t cleared. What’s the one action you still need to take?
- A user has the same SKU listed twice — once “inherited (from group)” and once “directly assigned.” Which one do you remove, and which command-family do you use?
Answers
- Click into the users in error list (Group → Licenses → the banner). The reason is a property of each user, not the group — the banner only counts; the cause lives on the user.
- Check
usageLocation(Get-MgUser -UserId <upn> -Property usageLocation). Set it withUpdate-MgUser -UserId <upn> -UsageLocation "IN"(or your country code), then reprocess. - True. A
MutuallyExclusiveViolationmeans the same plan is granted twice; disabling the duplicated plan on one assignment leaves it granted exactly once and clears the conflict. (Don’t remove a whole license.) - Reprocess the group (Group → Licenses → Reprocess). Provisioning is asynchronous; the fix doesn’t always auto-clear, and reprocess is also your test that the fix was correct.
- Remove the directly assigned copy (the group keeps re-applying the inherited one). Use
Set-MgUserLicense -RemoveLicenses @($skuId). You cannot remove the inherited copy per-user — that’s changed via group membership.
Glossary
- Group-based licensing (GBL) — assigning a license SKU to an Entra group so every member inherits it and is provisioned/deprovisioned automatically with membership.
- SKU / product / licensing plan — the license you purchase (e.g.
ENTERPRISEPACK= Microsoft 365 E3); a bundle of service plans, consumed one whole unit per user. - Service plan — an individually toggleable service inside a SKU (Exchange Online, Teams, SharePoint, Power BI, Intune…); conflicts occur at this level.
- Provisioning engine — the asynchronous background process that applies a group’s license to each member and parks failures in an error state.
- Usage location (
usageLocation) — the user’s two-letter ISO country code; required before location-dependent plans can be provisioned. Top cause of GBL failures when blank. - Inherited license — a license a user holds via group membership; cannot be removed per-user (change membership instead).
- Direct license — a license assigned straight to the user account; the usual source of drift and duplicate assignment.
- Users in error — the members of a group whose license provisioning failed; the list (and per-user reason) you actually act on.
MutuallyExclusiveViolation(conflicting service plans) — error when the same service plan is granted to a user by two licenses; fixed by disabling the duplicated plan on one assignment.CountViolation(not enough licenses) — error when a SKU’s consumed units have reached purchased, so a member can’t be allocated a unit.ProhibitedInUsageLocationViolation— error when a plan is legally unavailable in the user’s (set) usage-location country.- Disabled plans — the set of service plans switched off on a particular assignment; the mechanism for both conflict resolution and withholding services.
- License drift — divergence between the intended group-driven license state and the user’s effective state, usually from direct assignment layered on a group one.
- Reprocess — Group → Licenses action that re-runs provisioning for the group’s members; clears errors whose cause is resolved and serves as the test that a fix worked.
- Entra ID P1 — the license tier that includes group-based licensing (bundled in Microsoft 365 E3/E5, EMS, Business Premium); GBL itself carries no extra charge.
Next steps
You can now localise any group-based licensing error to a layer and a user, fix it, and reprocess. Build outward:
- Next: Microsoft Entra ID Fundamentals: Tenants, Users, Groups & RBAC — solidify the tenant/group/SKU model underneath all of this.
- Related: Entra ID Dynamic Groups: A Membership-Rule Cookbook That Actually Scales — drive licensing off attributes cleanly, and avoid the overlapping-membership conflicts.
- Related: Microsoft Entra Connect Sync Deep Dive: Designing Hybrid Identity with PHS, PTA, and Seamless SSO — get
usageLocationto flow in from on-premises AD so synced users never arrive blank. - Related: Automating Joiner-Mover-Leaver with Entra ID Lifecycle Workflows and Custom Extensions — the joiner-mover-leaver automation that moves people between groups and triggers re-licensing.
- Related: Set Up Azure Budgets: Threshold Alerts to Email, Action Groups, and Automation — keep an eye on the seat spend that group-based licensing scales up.