Photo by Eilis Garvey on Unsplash
EKS extended support cost is an extra $0.50 per cluster per hour on top of the $0.10 standard control-plane fee, so $0.60 in total, or about $365 more per cluster each month (US East, September 2026). A cluster pays it when its Kubernetes version is past 14 months of standard support and its upgrade policy is EXTENDED, which is the default.
EKS doesn’t ask before it moves a cluster into extended support. The version ages out, the upgrade policy says EXTENDED, and the control-plane line on the bill goes up sixfold. Nothing breaks, so the first sign is usually a Cost Explorer spike weeks later.
This example is for platform engineers who want one table of every cluster, its version’s support status, its upgrade policy and the EKS extended support cost it adds, plus the upgrade-readiness insights that stand between each cluster and the next version. It only reads. If you’re auditing the same clusters for exposure, run it next to the script that finds EKS clusters with a public API endpoint.
What does EKS extended support cost?
EKS charges per cluster-hour for the control plane, and the rate depends on whether the cluster’s Kubernetes version is in standard or extended support. Worker nodes, Fargate and add-ons are billed separately and don’t change.
| Support period | Length | Price per cluster-hour | About per month (730 h) |
|---|---|---|---|
| Standard support | 14 months from the EKS release | $0.10 | $73 |
| Extended support | The next 12 months | $0.60 ($0.10 + $0.50) | $438 |
Prices as of September 2026 for US East (N. Virginia), from the AWS Price List API (AmazonEKS offer, usage types Hours:perCluster and Hours:extendedSupport) and the Amazon EKS pricing page. Provisioned control-plane tiers are priced separately.
Worked example
Three clusters left on Kubernetes 1.32 after 23 March 2026, when its standard support ended: 3 × $0.50 × 730 hours = $1,095 a month in surcharge alone. Their control planes cost 3 × $0.60 × 730 = $1,314 a month instead of 3 × $0.10 × 730 = $219. Upgrading all three to a version in standard support removes the $1,095 from the next hour on.
How do versions and upgrade policies decide the bill?
Each Kubernetes minor version gets 14 months of standard support on EKS, then 12 months of extended support: 26 months in total. Upstream, the project patches only the three most recent minor releases for about a year each, per the Kubernetes release support policy, so extended support is AWS backporting fixes you’d no longer get from the community.
The cluster’s upgradePolicy.supportType decides what happens at the end of standard support:
EXTENDED(the default for new and existing clusters): the cluster stays on its version and starts paying the extended rate from the day standard support ends (UTC).STANDARD: EKS upgrades the control plane to the next version at the end of standard support. No surcharge, but the upgrade happens on AWS’s schedule, not yours.
You can only change the policy while the cluster is in standard support. Once it’s in extended support, the only way off the surcharge is an upgrade. At the end of extended support, EKS upgrades the control plane anyway, without further notice; nodes and add-ons stay behind.
| Version | End of standard support | End of extended support |
|---|---|---|
| 1.32 | 23 March 2026 | 23 March 2027 |
| 1.33 | 29 July 2026 | 29 July 2027 |
| 1.34 | 2 December 2026 | 2 December 2027 |
| 1.35 | 27 March 2027 | 27 March 2028 |
| 1.36 | 2 August 2027 | 2 August 2028 |
Dates from the EKS release calendar as of September 2026. The script reads them live from DescribeClusterVersions, so you don’t have to maintain this table.
What does the script do?
- Loads the version calendar
DescribeClusterVersionswithincludeAllreturns each version’sversionStatus(STANDARD_SUPPORT,EXTENDED_SUPPORTorUNSUPPORTED) and its end dates. - Reads every cluster
ListClustersandDescribeClustergive the Kubernetes version andupgradePolicy.supportType. - Prices the surchargeClusters in extended support get the extra $0.50 × 730 hours; override the rate with
--extra-ratefor other Regions. - Looks aheadClusters whose standard support ends within
--days(default 90) are flagged as entering extended support or, with policySTANDARD, as due for an automatic upgrade. - Checks upgrade readinessFor flagged clusters,
ListInsightscountsUPGRADE_READINESSinsights inERRORorWARNING, such as removed Kubernetes APIs still in use.
Prerequisites
- Node.js 18 or later, npm and
tsx, plus@aws-sdk/client-eks. - A read-only profile set up as in the guide to AWS SDK v3 credential providers for profiles and SSO.
- The Regions your clusters run in. The script checks the Regions you pass; it doesn’t discover them.
Which IAM permissions does it need?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadEksVersionsAndClusters",
"Effect": "Allow",
"Action": [
"eks:DescribeClusterVersions",
"eks:ListClusters",
"eks:DescribeCluster",
"eks:ListInsights"
],
"Resource": "*"
}
]
}
All four actions are read-only and none of them needs Kubernetes RBAC access inside the cluster. The IAM policy generator for TypeScript code produces the same list from the script if you want to double-check it.
The script to find EKS clusters on extended support
// find-eks-clusters-on-extended-support.ts
// Report only. For every EKS cluster in the chosen Regions: its Kubernetes version, the version's support
// status and dates, the cluster's upgrade policy, the extra monthly cost of extended support, and how many
// upgrade-readiness insights are failing. Nothing is modified.
// Usage:
// npx tsx find-eks-clusters-on-extended-support.ts [--regions us-east-1,eu-west-1] [--days 90] [--extra-rate 0.50]
import {
EKSClient,
DescribeClusterCommand,
paginateDescribeClusterVersions,
paginateListClusters,
paginateListInsights,
type ClusterVersionInformation,
} from "@aws-sdk/client-eks";
const args = process.argv.slice(2);
const flag = (name: string): string | undefined => {
const i = args.indexOf(name);
return i >= 0 ? args[i + 1] : undefined;
};
const regions = (flag("--regions") ?? process.env.AWS_REGION ?? "us-east-1")
.split(",")
.map((r) => r.trim())
.filter(Boolean);
const warnDays = Number(flag("--days") ?? "90");
// Extended support surcharge per cluster-hour on top of standard support (US East, N. Virginia, Sep 2026).
const extraRate = Number(flag("--extra-rate") ?? "0.50");
const HOURS_PER_MONTH = 730;
const DAY_MS = 86_400_000;
interface Row {
Region: string;
Cluster: string;
Version: string;
Support: string;
StandardEnds: string;
ExtendedEnds: string;
Policy: string;
ExtraPerMonth: string;
UpgradeInsights: string;
Action: string;
}
const day = (d: Date | undefined): string => (d ? d.toISOString().slice(0, 10) : "?");
const errText = (err: unknown): string => (err instanceof Error ? `${err.name}: ${err.message}` : String(err));
async function versionTable(eks: EKSClient): Promise<Map<string, ClusterVersionInformation>> {
const map = new Map<string, ClusterVersionInformation>();
for await (const page of paginateDescribeClusterVersions({ client: eks }, { includeAll: true })) {
for (const v of page.clusterVersions ?? []) {
if (v.clusterVersion) map.set(v.clusterVersion, v);
}
}
return map;
}
// Counts UPGRADE_READINESS insights in ERROR or WARNING for the cluster's next upgrade.
async function upgradeInsights(eks: EKSClient, clusterName: string): Promise<string> {
let error = 0;
let warning = 0;
try {
const pages = paginateListInsights(
{ client: eks },
{ clusterName, filter: { categories: ["UPGRADE_READINESS"], statuses: ["ERROR", "WARNING"] } },
);
for await (const page of pages) {
for (const insight of page.insights ?? []) {
if (insight.insightStatus?.status === "ERROR") error++;
else warning++;
}
}
} catch (err) {
return `unavailable (${err instanceof Error ? err.name : "error"})`;
}
return error + warning === 0 ? "none failing" : `${error} error, ${warning} warning`;
}
async function scanRegion(region: string): Promise<Row[]> {
const eks = new EKSClient({ region });
const versions = await versionTable(eks);
const rows: Row[] = [];
const now = Date.now();
for await (const page of paginateListClusters({ client: eks }, {})) {
for (const name of page.clusters ?? []) {
const { cluster } = await eks.send(new DescribeClusterCommand({ name }));
const version = cluster?.version ?? "?";
const info = versions.get(version);
const policy = cluster?.upgradePolicy?.supportType ?? "?";
const status = info?.versionStatus ?? "UNKNOWN";
const stdEnd = info?.endOfStandardSupportDate;
const daysToStdEnd = stdEnd ? Math.ceil((stdEnd.getTime() - now) / DAY_MS) : undefined;
let extra = "-";
let action = "ok";
if (status === "EXTENDED_SUPPORT") {
extra = `$${(extraRate * HOURS_PER_MONTH).toFixed(2)}`;
action = `upgrade before ${day(info?.endOfExtendedSupportDate)} (auto-upgrade after)`;
} else if (status === "STANDARD_SUPPORT" && daysToStdEnd !== undefined && daysToStdEnd <= warnDays) {
action = policy === "STANDARD"
? `auto-upgrade after ${day(stdEnd)} (policy STANDARD)`
: `enters extended support in ${daysToStdEnd} days`;
} else if (status === "UNKNOWN") {
action = "version not in DescribeClusterVersions";
}
rows.push({
Region: region,
Cluster: name,
Version: version,
Support: status,
StandardEnds: day(stdEnd),
ExtendedEnds: day(info?.endOfExtendedSupportDate),
Policy: policy,
ExtraPerMonth: extra,
UpgradeInsights: action === "ok" ? "-" : await upgradeInsights(eks, name),
Action: action,
});
}
}
return rows;
}
async function main(): Promise<void> {
const rows: Row[] = [];
for (const region of regions) {
try {
rows.push(...(await scanRegion(region)));
} catch (err) {
console.error(`${region}: ${errText(err)}`);
process.exitCode = 1;
}
}
console.table(rows);
const extended = rows.filter((r) => r.Support === "EXTENDED_SUPPORT");
const monthly = extended.length * extraRate * HOURS_PER_MONTH;
console.log(
`${rows.length} clusters checked, ${extended.length} on extended support ` +
`(about $${monthly.toFixed(2)}/month extra at $${extraRate.toFixed(2)} per cluster-hour).`,
);
console.log("Report only: nothing was modified.");
}
main().catch((err) => {
console.error(errText(err));
process.exit(1);
});
The paginators follow nextToken for you; the guide to AWS SDK v3 paginators explains the pattern if you adapt the script.
How do you run it?
npm install @aws-sdk/client-eks
npm install --save-dev tsx typescript @types/node
AWS_PROFILE=readonly npx tsx find-eks-clusters-on-extended-support.ts --regions us-east-1,eu-west-1 --days 90
Sample output
┌─────────┬─────────────┬────────────┬─────────┬────────────────────┬──────────────┬──────────────┬────────────┬───────────────┬──────────────────────┬───────────────────────────────────────────────────┐
│ (index) │ Region │ Cluster │ Version │ Support │ StandardEnds │ ExtendedEnds │ Policy │ ExtraPerMonth │ UpgradeInsights │ Action │
├─────────┼─────────────┼────────────┼─────────┼────────────────────┼──────────────┼──────────────┼────────────┼───────────────┼──────────────────────┼───────────────────────────────────────────────────┤
│ 0 │ 'us-east-1' │ 'payments' │ '1.32' │ 'EXTENDED_SUPPORT' │ '2026-03-23' │ '2027-03-23' │ 'EXTENDED' │ '$365.00' │ '1 error, 1 warning' │ 'upgrade before 2027-03-23 (auto-upgrade after)' │
│ 1 │ 'us-east-1' │ 'batch' │ '1.34' │ 'STANDARD_SUPPORT' │ '2026-12-02' │ '2027-12-02' │ 'STANDARD' │ '-' │ 'none failing' │ 'auto-upgrade after 2026-12-02 (policy STANDARD)' │
│ 2 │ 'us-east-1' │ 'web' │ '1.36' │ 'STANDARD_SUPPORT' │ '2027-08-02' │ '2028-08-02' │ 'EXTENDED' │ '-' │ '-' │ 'ok' │
│ 3 │ 'eu-west-1' │ 'reports' │ '1.33' │ 'EXTENDED_SUPPORT' │ '2026-07-29' │ '2027-07-29' │ 'EXTENDED' │ '$365.00' │ 'none failing' │ 'upgrade before 2027-07-29 (auto-upgrade after)' │
└─────────┴─────────────┴────────────┴─────────┴────────────────────┴──────────────┴──────────────┴────────────┴───────────────┴──────────────────────┴───────────────────────────────────────────────────┘
4 clusters checked, 2 on extended support (about $730.00/month extra at $0.50 per cluster-hour).
Report only: nothing was modified.
Cluster names are illustrative. payments and reports already pay the surcharge, and payments has an upgrade-readiness error to fix first. batch has policy STANDARD, so it won’t cost more, but EKS will upgrade it after 2 December 2026 whether or not its workloads are ready.
How do you get a cluster off extended support?
- Clear the insightsRun
aws eks list-insights --cluster-name paymentsand fix every upgrade-readiness error, usually manifests that still call removed APIs. Insights look at API usage over a rolling 30-day window, so a fixed issue can take time to turn green. - Match node versionsManaged and Fargate nodes must be on the control plane’s minor version before you upgrade it.
- Upgrade one minor version at a time
aws eks update-cluster-version --name payments --kubernetes-version 1.33. EKS can’t skip versions, so 1.32 to 1.35 is three upgrades, each followed by nodes and add-ons (VPC CNI, CoreDNS,kube-proxy). - Stop when you reach standard supportThe surcharge stops at the first version in standard support. You can roll back within 7 days if something breaks.
- Choose the policy on purposeFor clusters that must never cost more, set
aws eks update-cluster-config --name batch --upgrade-policy supportType=STANDARDwhile they’re still in standard support, and accept the automatic upgrade.
Engines outside EKS follow the same pattern: the script to find Lambda functions on deprecated runtimes covers another lifecycle deadline that’s easy to miss.
Troubleshooting
UpgradeInsightsshowsunavailable. The profile lackseks:ListInsights, or the Region doesn’t return insights for that cluster. The rest of the row is still correct.- A version shows
UNKNOWN. The version isn’t in theDescribeClusterVersionsresponse for that Region. Check that you’re on a recent SDK release. - The surcharge doesn’t match your bill. The script uses 730 hours and the US East rate. Compare with the
AmazonEKSusage types in the Cost Explorer script that breaks costs down by service. - You can’t switch the policy to
STANDARD. The cluster is already in extended support. Upgrade it first.
To catch the next surcharge before it lands, add an AWS Budgets alert created with SDK v3 scoped to Amazon EKS. More cost checks like this one are in the library of practical AWS SDK examples.
Ask ChatWithCloud instead
For a quick answer in one Region, ask ChatWithCloud “Which EKS clusters in us-east-1 run a Kubernetes version in extended support?” It writes AWS SDK for JavaScript v2 code, runs it on your machine with your profile and summarizes the result, one profile and Region per session. SDK v2 reached end of support in September 2025, so newer EKS fields may be missing from its answers; how ChatWithCloud runs AWS SDK code locally explains the loop. It runs changes without asking for confirmation, so connect ChatWithCloud to a read-only AWS profile. When the bill has already jumped, the walkthrough to ask AI why your AWS bill increased starts from Cost Explorer instead.
Frequently asked questions
How much does EKS extended support cost per cluster?
$0.60 per cluster-hour in US East as of September 2026: the $0.10 standard fee plus a $0.50 surcharge. That’s about $438 a month per cluster, $365 of it extra.
Is EKS extended support enabled by default?
Yes. New and existing clusters have the upgrade policy EXTENDED unless you set STANDARD, which makes EKS upgrade the cluster at the end of standard support instead.
Can I turn off extended support for a cluster that’s already in it?
No. You can only change the upgrade policy while the cluster runs a version in standard support. Upgrade the cluster to stop the charge.
What happens when extended support ends?
EKS upgrades the control plane to the oldest supported version at some point after the end date, without a specific notice. Nodes and add-ons aren’t upgraded, and an automatic upgrade can’t be rolled back.
Related guides
Ask your AWS account in plain English
Your first 15 runs are free, with no OpenAI key needed.
npx chatwithcloud