cost agent's cross-account audit returned zeros - the assumed role lacked ce:GetCostAndUsage and it reported "no...
Fixes a cross-account cost audit that silently reports zero spend because the assumed role is missing billing read permissions. Use it when an agent's audit of a linked or member account returns "no spend found" with no error. Key trigger: GetCostAndUsage succeeds but returns empty results for an account you know has spend.
TL;DR
An empty Cost Explorer result with no error usually means the role cannot read billing data, not that spend is zero. Check which role the agent actually assumed, confirm Cost Explorer is enabled in the payer account, and add the billing read permissions to the role. Never let the agent report "all clean" on an empty result without this check.
cost agent's cross-account audit returned zeros - the assumed role lacked ce:GetCostAndUsage and it reported "no spend found"Steps
- Confirm the identity the agent is actually using:
aws sts get-caller-identityExpected: the ARN of the assumed role, not the agent's own user. Compare it to the role you intended.
- Run the same query by hand:
aws ce get-cost-and-usage --time-period Start=2026-09-01,End=2026-10-01 --granularity MONTHLY --metrics UnblendedCostExpected: if you get empty results with no error here too, it is a permissions or setup problem, not an agent bug.
- Check the role's policy allows the billing reads the audit needs: ce:GetCostAndUsage, plus ce:GetCostForecast or ce:GetReservationUtilization if the audit uses them. Billing data is read from the payer account, so the grant lives there.
Expected: the policy lists those actions and the agent's next run returns real numbers.
- Confirm Cost Explorer is enabled in the payer account (Billing, then Cost Explorer in the console). If it was never enabled, no API call returns data.
Expected: Cost Explorer shows charts in the console, and the API returns the same numbers.
- Make the agent treat empty results as a failure: if a query returns zero rows for an account with known spend, halt and flag instead of reporting "no spend found".
Expected: silent zeros become loud errors.
Use this when
- a cross-account audit returns zeros
- the agent reports "no spend found" for a busy account
- results are empty but there is no AccessDenied error
Not for this skill when
- you get an explicit AccessDeniedException (same fix, but at least it is loud; also check the role trust policy)
- it is a brand-new account with genuinely no spend
- the CUR bucket is unreadable (that is an S3 and KMS permission problem)
Variant phrasings
- "GetCostAndUsage returns empty"
- "Cost Explorer API no data for linked account"
- "assumed role cannot see billing"
Why it happens
Billing APIs are payer-level and off by default for IAM roles; many orgs grant EC2 and CloudWatch read but never the ce actions. Cost Explorer returns empty instead of erroring for some of these gaps, so the agent's "no data" looks exactly like "no spend".
Edge cases
- The role must also be assumable from the agent's account; check the trust policy, not just the permissions policy.
- Some orgs use SCPs that block the billing actions; then the fix lives in the org policy, not the role.
- Cost Explorer data only starts on the day it is enabled. There is no backfill, so a newly enabled account legitimately shows zeros for history.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_czrxhjwEQupxHjqFV-r1jg
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.