The resource is tagged. You can see the tag in the console. The tag key is activated. And the cost allocation column is still empty, or half empty, or full for EC2 and blank for everything else. Every one of those outcomes has a documented cause, and none of them is a bug.
Why is the column empty when the resource is clearly tagged?
Because tagging a resource and activating a cost allocation tag are two separate acts, and only the second one affects your bill. The AWS cost allocation tags documentation is explicit that there are two kinds, AWS-generated and user-defined, and that "you must activate both types of tags separately before they can appear in Cost Explorer or on a cost allocation report."
So a perfectly tagged estate produces exactly zero cost allocation data until someone opens the Billing console and activates the keys. That is the single most common cause, and it is invisible from the resource side: nothing in the EC2 or S3 console tells you the tag is not billing-active.
How long does activation take?
Up to 48 hours in the worst case, in two separate stages. Per the activating user-defined cost allocation tags page: "after you create and apply user-defined tags to your resources, it can take up to 24 hours for the tag keys to appear on your cost allocation tags page for activation. It can then take up to 24 hours for tag keys to activate."
| Stage | What you are waiting for | Documented delay |
|---|---|---|
| 1 | The tag key to appear in the list you can activate from | Up to 24 hours |
| 2 | The activated key to take effect | Up to 24 hours |
| 3 | Cost Explorer and the CUR to refresh | At least once per day |
If you tagged something an hour ago and it is not in the activation list, nothing has gone wrong yet. Come back tomorrow before debugging.
Does activating a tag fill in the past?
Not by itself, and this is the sentence worth pinning to the wall. The user-defined cost allocation tags page states: "Tags are not applied to resources that were created before the tags were created."
Two different gaps hide in that. A tag that did not exist on the resource in June produces no June data, ever, whatever you do later. And a tag that did exist on the resource but was not activated until November produces no June data until you ask for a backfill, which is a separate and recoverable problem. Distinguishing them decides whether your Q2 chargeback is retrievable or gone.
What can a backfill actually recover?
Backfill exists and is genuinely useful: "management account users can request a backfill of cost allocation tags for up to twelve months. When you request a backfill, the current activation status of the tags are backfilled for the duration of your choice."
Read that carefully: it backfills activation status, not tags. AWS's
own worked example makes the limit concrete. A Project tag is
put on resources in June 2023 and activated in November 2023. In December you
backfill from January 2023. The result: "the tag values associated to the
Project tag will be available with the cost data from June 2023
to December 2023. However, January 2023 to May 2023 will not have tag values
associated because the Project tag was not present in the AWS
Resources."
The governing rule is stated as a note: "the resource tag must be historically assigned to the AWS Resource for the backfilled cost data to be available." Backfill retrieves months you failed to activate. It cannot retrieve months you failed to tag.
Three operational constraints go with it:
- "You can't submit a new backfill request when there is a backfill in progress."
- "You can only submit a new backfill request once every 24 hours."
- It updates Cost Explorer, Data Exports and the CUR automatically, but "because these services refresh your data once every 24 hours, your backfill won't update as soon as it succeeds."
And a sharp edge in the other direction: backfill applies current status, so
it deactivates too. "For example, a Team tag was active in prior
months, but currently is set to inactive status. Backfilling
will result in the Team tag being deactivated and removed from
the cost data for previous months." A backfill run to fix one tag can strip
historical data for another. Check the full activation list before you
confirm.
Which account can do any of this?
Only one. AWS states that "only the management account in an organization and single accounts that aren't members of an organization have access to the cost allocation tags manager in the Billing console," and backfill is management-account-only as well.
A member account can tag its resources all day and cannot activate a single key. If you run a multi-account estate, tagging standards are a member-account job and activation is a management-account job, and the handoff between them is where tag programmes quietly stall.
There is a related trap when accounts move. AWS's stated best practice: "reactivate your cost allocation tags when moving organizations. When an account moves to another organization as a member, previously activated cost allocation tags for that account lose their 'active' status and need to be activated again by the new management account." An acquisition or an internal org restructure silently turns your allocation off.
Why does the tag key look different in CUR 2.0?
Because it is prefixed by source. In the legacy cost allocation report the
rule is simple: "AWS-generated tag names and values are automatically
assigned the aws: prefix, which you can't assign. User-defined
tag names have the prefix user: in the cost allocation report."
CUR 2.0 replaced that with a single
tags map and five source prefixes, documented in the
CUR 2.0 tags column reference:
| Prefix | Where the tag came from |
|---|---|
resourceTags/ | Tags applied directly to AWS resources |
userAttribute/ | User attributes imported from IAM Identity Center |
accountTag/ | Tags applied at the AWS account level |
costCategory/ | Tags derived from AWS Cost Categories |
iamPrincipal/ | Tags applied to IAM principals |
A query written against user:team and pointed at CUR 2.0 finds
nothing, because the key is now resourceTags/team. Same tag,
same activation, different column name. The
CUR troubleshooting guide
makes the general version of this point about schema drift: "because the
columns included in your report can change, it's a best practice to reference
column names instead of column numbers in any custom queries or tables based
on your report."
The CUR 2.0 map has a second gate on top of activation: "tag keys only appear in this column if they've been enabled as cost allocation tags in the Billing console. After being enabled, a particular key only appears in the map column if it has a value that applies to the specific line item." An activated key with no value on a given row is absent from that row's map rather than present-and-null, which changes how you write the query.
What else silently produces no tag data?
These are documented behaviours, not edge cases, and each looks like a bug:
- Non-metered services. "User-defined tags on non-metered services can be activated (for example, Account Tagging). However, these tags will not populate in the Cost Management suite because these services are not metered." The key shows as Active and produces nothing.
- Service-launched resources. "Some services launch other AWS resources that the service uses, such as Amazon EMR launching an EC2 instance." The cost lands on the EC2 instance, so the EC2 instance is what has to carry the tag, not just the EMR cluster.
- AWS Marketplace. "AWS Marketplace line items are tagged with the associated Amazon EC2 instance tag," so Marketplace charges inherit from the instance rather than carrying their own.
- Per-service differences. "The behavior of cost allocation tags varies across AWS services. To learn more about the cost allocation tag behavior for a supported service, refer to the service's documentation." There is no universal rule; there are per-service rules.
- Shared resources with no owner column. A NAT Gateway or an EKS node serves many teams and carries one tag. That is not a tagging failure, it is a splitting problem, and it needs split cost allocation data for pods or usage-type analysis for network charges.
How many keys can you activate?
Per the Billing quotas and restrictions page:
| Quota | Value |
|---|---|
| Maximum active cost allocation tag keys, per payer account | 500 |
| Tags activated or deactivated in one API or console request | 20 |
The 500 is adjustable through Service Quotas. One exemption is documented:
"tags that are automatically activated don't count towards your cost
allocation tag quota, such as the awsApplication tag." That tag
is added automatically to resources associated with applications set up in
AWS Service Catalog AppRegistry, and activated for you. You can deactivate
it, but AWS notes "if you deactivate the tag, it won't be automatically
activated again."
Bulk activation is scriptable rather than a console slog, via UpdateCostAllocationTagsStatus, in batches of twenty.
How do you measure what is actually untagged?
Measure it in dollars, not in resource counts. Ninety percent of resources tagged can still be sixty percent of spend untagged, because the untagged ten percent is where the large instances live. In CUR 2.0:
SELECT CASE WHEN tags['resourceTags/team'] IS NULL
THEN 'untagged' ELSE 'tagged' END AS state,
sum(line_item_unblended_cost) AS cost
FROM cur2
WHERE bill_billing_period_start_date = TIMESTAMP '2026-08-01 00:00:00'
AND line_item_line_item_type IN ('Usage', 'DiscountedUsage', 'SavingsPlanCoveredUsage')
GROUP BY 1
Then rank the gap by what it is worth fixing, which is almost never the longest list:
SELECT line_item_product_code,
line_item_resource_id,
sum(line_item_unblended_cost) AS cost
FROM cur2
WHERE bill_billing_period_start_date = TIMESTAMP '2026-08-01 00:00:00'
AND line_item_line_item_type IN ('Usage', 'DiscountedUsage', 'SavingsPlanCoveredUsage')
AND tags['resourceTags/team'] IS NULL
GROUP BY 1, 2
ORDER BY 3 DESC
LIMIT 50
Two things about those queries are worth copying rather than the SQL itself.
The line item type filter is not just Usage. The
line item column reference
defines Usage as "any usage that is charged at On-Demand Instance
rates", which excludes DiscountedUsage ("the rate of any
instances for which you had Reserved Instance (RI) benefits") and
SavingsPlanCoveredUsage ("any On-Demand cost that is covered by
your Savings Plan"). Those are tagged resources doing real work. Filter to
Usage alone and a heavily committed fleet mostly disappears from
your coverage number. Excluding Tax, Refund,
Credit and the various fee types is the part you do want, since
those are not tagged resources and would otherwise inflate the untagged
bucket.
line_item_resource_id is not always there. AWS
marks it "Table configuration: Added by: INCLUDE RESOURCES", and notes it "is
blank for usage types that aren't associated with an instantiated host, such
as data transfers and API requests". If the second query returns nothing,
check that configuration before concluding you are fully tagged.
Both are instances of a wider issue, covered in why Cost Explorer and your CUR disagree: the number you get depends on which line items you decided were in scope.
The order that actually works
- Tag the resources first. Nothing else recovers a month you did not tag.
- Wait up to 24 hours for keys to surface in the management account.
- Activate them, in batches of 20, and wait up to another 24 hours.
- Backfill up to twelve months, once you are sure the current activation set is the one you want applied to history.
- Measure the untagged share in dollars, monthly, and treat it as the metric rather than tag coverage by resource count.
For the cost that no amount of tagging will ever reach, because there is no resource to tag or because the month is already closed, the complementary tool is a cost category: AWS applies those by rule and, unlike tags, applies them retroactively to the start of the current month. What they can and cannot do is in what split charge rules can and can't do.