kubernetes/kops · error

kops currently only supports re-use of either NAT EC2 Instan

Error message

kops currently only supports re-use of either NAT EC2 Instances or NAT Gateways. We will support more eventually! Please see https://github.com/kubernetes/kops/issues/1530

What it means

When a subnet's `egress` value is set but does not match any supported reuse target (nat-*, eipalloc-*, i-*, tgw-*, or the literal External), the AWS network builder refuses to construct egress tasks. kops only knows how to re-use NAT Gateways, Elastic IPs, NAT EC2 instances, Transit Gateways, or an external/implicit egress path; anything else is unsupported. This is a config-value validation error at `kops update cluster` time.

Source

Thrown at pkg/model/awsmodel/network.go:496

				c.AddTask(ngw)

			} else if strings.HasPrefix(egress, "i-") {

				in = &awstasks.Instance{
					Name:      new(egress),
					Lifecycle: b.Lifecycle,
					ID:        new(egress),
					Shared:    new(true),
					Tags:      nil, // We don't need to add tags here
				}

				c.EnsureTask(in)
			} else if strings.HasPrefix(egress, "tgw-") {
				tgwID = &egress
			} else if egress == "External" {
				// Nothing to do here
			} else {
				return fmt.Errorf("kops currently only supports re-use of either NAT EC2 Instances or NAT Gateways. We will support more eventually! Please see https://github.com/kubernetes/kops/issues/1530")
			}
		} else {

			// Every NGW needs a public (Elastic) IP address, every private
			// subnet needs a NGW, lets create it. We tie it to a subnet
			// so we can track it in AWS
			eip := &awstasks.ElasticIP{
				Name:                           new(zone + "." + b.ClusterName()),
				Lifecycle:                      b.Lifecycle,
				AssociatedNatGatewayRouteTable: egressRouteTable,
			}

			if publicIP != "" {
				eip.PublicIP = new(publicIP)
				eip.Tags = b.CloudTags(*eip.Name, true)
			} else {
				eip.Tags = b.CloudTags(*eip.Name, false)
			}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Change `egress` to one of the supported forms: empty (kops-managed NAT gateway), nat-<id>, eipalloc-<id>, i-<id>, tgw-<id>, or the literal `External`.
  2. If you intended a VPC endpoint or proxy egress, remove egress and implement routing outside kops (e.g. route tables pointing at the endpoint), or use `External` with pre-created routes.
  3. Verify the ID prefix with `aws ec2 describe-nat-gateways` / `describe-transit-gateways` and paste the correct resource into the spec.
  4. Apply the fixed spec (`kops replace -f` / `kops edit cluster`) and re-run `kops update cluster`. See kops issue #1530 for supported egress options.

Example fix

# before
subnets:
- name: private-a
  type: Private
  zone: us-east-1a
  egress: vpce-0abc123   # unsupported
# after
subnets:
- name: private-a
  type: Private
  zone: us-east-1a
  egress: nat-0abc123    # supported: reuse existing NAT gateway
# or simply omit egress to let kops create one
Defensive patterns

Strategy: validation

Validate before calling

// Only allow known egress forms before handing the spec to kops
var egressRe = regexp.MustCompile(`^(nat-[0-9a-f]+|eipalloc-[0-9a-f]+|i-[0-9a-f]+|tgw-[0-9a-f]+|External|)$`)
func validEgress(v string) bool { return egressRe.MatchString(v) }

Type guard

func isSupportedEgress(egress string) bool {
    switch {
    case egress == "", egress == "External":
        return true
    case strings.HasPrefix(egress, "nat-"), strings.HasPrefix(egress, "eipalloc-"),
        strings.HasPrefix(egress, "i-"), strings.HasPrefix(egress, "tgw-"):
        return true
    }
    return false
}

Try / catch

out, err := exec.Command("kops", "update", "cluster", "--yes").CombinedOutput()
if err != nil && strings.Contains(string(out), "only supports re-use of either NAT EC2 Instances or NAT Gateways") {
    log.Fatalf("egress value not supported; use nat-*/eipalloc-*/i-*/tgw-*/External or omit it")
}

Prevention

When it happens

Trigger: Setting `egress` on a private subnet to an arbitrary string such as a VPC endpoint ID (vpce-...), a placeholder like "nat", a peering connection ID (pcx-...), a typo like "NAT-Gateway", or a malformed resource ID.

Common situations: Users assuming any AWS resource ID works as egress and trying vpce- endpoints (not supported here); typos when pasting IDs; docs/examples from older kops versions using values that are no longer accepted; attempting IGW-based or proxy egress via the egress field.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/49378e424678f2ba. Report an issue: GitHub.