Skip to main content
Back to the Azure Footguns Database
GovernanceLowCommonAZF-0046

An empty resource group is dead scaffolding that complicates governance

A resource group that contains nothing still carries tags, RBAC assignments, policy scope, and a place in every report, adding noise no one ever cleans up.

Footgun ID
AZF-0046 (Azure Footgun No. 46)
Azure service
Azure Resource Manager
Resource type
Microsoft.Resources/resourceGroups
Updated
July 1, 2026

What it is

A resource group with no child resources inside it. It occupies a slot in your subscription, keeps its tags and role assignments, and shows up in every inventory and policy scope, but it holds nothing.

Impact (governance)
No direct charge; the harm is inventory clutter and misleading governance scope
Basis: Azure behavior (authored assessment). Figures are estimates, not measurements.

Why it happens

Resource groups are cheap to create and easy to forget. They pile up from decommissioned projects whose contents were deleted one at a time while the container was left behind, from templates that provision a group before the deployment that fills it fails, and from reorganizations that move resources elsewhere. Because Azure never bills for the group itself, no cost signal ever nudges anyone to remove it.

The trap is that an empty group is not inert. It can still hold RBAC assignments that grant standing access, it counts against the scope that policies and reports iterate over, and its tags can skew a governance dashboard that keys off resource-group metadata. Every empty group is a question an auditor has to answer.

What it costs / blast radius

A resource group has no meter, so this costs nothing on the bill. The harm is entirely governance: empty groups inflate inventory counts, leave role assignments attached to scopes that do nothing, and make it harder to reason about what a subscription actually contains. Multiply that across a large estate and cleanups turn into archaeology. (Authored assessment of Azure behavior.)

See it

Find them: resource groups with zero child resources
ResourceContainers
| where type =~ 'microsoft.resources/subscriptions/resourcegroups'
| project rgId = tolower(id), rgName = name, subscriptionId, location
| join kind=leftouter (
    Resources
    | extend rgId = tolower(strcat('/subscriptions/', subscriptionId,
                                   '/resourcegroups/', resourceGroup))
    | summarize resourceCount = count() by rgId
  ) on rgId
| where isnull(resourceCount) or resourceCount == 0
| project rgName, subscriptionId, location
Fix: delete the empty group after confirming its role assignments are not needed
// Check for standing RBAC first, then remove the empty container.
az role assignment list --resource-group rg-legacy-project -o table
az group delete --name rg-legacy-project --yes

How StratoLens helps

StratoLens flags empty resource groups automatically and continuously across every subscription in your tenant, so dead scaffolding does not accumulate in the corners nobody opens. You get a clean answer to "what is actually in this subscription" instead of a list padded with containers that hold nothing.

Start Your 28-Day Free Trial

Every feature unlocked. Deploys to your Azure tenant. No data leaves your tenant.

Available now on the Azure Marketplace.

Built for Azure infrastructure teams who need complete visibility across their entire estate.