Azure Identity

Group-Based Licensing Errors in Entra ID: Fixing Conflicts and License Drift

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 → LicensesReprocess

Learning objectives

By the end of this article you can:

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

Security notes

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:

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

  1. A group’s Licenses blade says “12 users couldn’t be assigned.” Where do you click next, and where does the actual reason live?
  2. New cloud-only users in a licensed group have no mailbox. What single attribute do you check first, and what command sets it?
  3. True or false: disabling the Teams service plan on one of two conflicting assignments is the right way to clear a MutuallyExclusiveViolation.
  4. You corrected a user’s usage location but their error hasn’t cleared. What’s the one action you still need to take?
  5. 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

  1. 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.
  2. Check usageLocation (Get-MgUser -UserId <upn> -Property usageLocation). Set it with Update-MgUser -UserId <upn> -UsageLocation "IN" (or your country code), then reprocess.
  3. True. A MutuallyExclusiveViolation means 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.)
  4. 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.
  5. 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

Next steps

You can now localise any group-based licensing error to a layer and a user, fix it, and reprocess. Build outward:

Entra IDLicensingGroup-Based LicensingTroubleshootingMicrosoft GraphAzure ADIdentityM365
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments

Keep Reading