kubernetes/kops · error
error associating VPC with hosted zone %q: %v
Error message
error associating VPC with hosted zone %q: %v
What it means
kOps' DNSZone task failed to associate a VPC with an existing private Route53 hosted zone while applying AWS changes. kOps calls Route53's AssociateVPCWithHostedZone when a private zone's VPC associations need updating; any AWS API rejection is wrapped in this error. It indicates the zone will not be resolvable from the cluster's VPC as intended.
Source
Thrown at upup/pkg/fi/cloudup/awstasks/dnszone.go:216
e.ZoneID = response.HostedZone.Id
} else {
if changes.PrivateVPC != nil {
request := &route53.AssociateVPCWithHostedZoneInput{
HostedZoneId: a.ZoneID,
VPC: &route53types.VPC{
VPCId: e.PrivateVPC.ID,
VPCRegion: route53types.VPCRegion(t.Cloud.Region()),
},
}
changes.PrivateVPC = nil
klog.V(2).Infof("Updating DNSZone %q", name)
_, err := t.Cloud.Route53().AssociateVPCWithHostedZone(ctx, request)
if err != nil {
return fmt.Errorf("error associating VPC with hosted zone %q: %v", name, err)
}
}
empty := &DNSZone{}
if !reflect.DeepEqual(empty, changes) {
klog.Warningf("cannot apply changes to DNSZone %q: %v", name, changes)
}
}
// We don't tag the zone - we expect it to be shared
return nil
}
type terraformRoute53ZoneAssociation struct {
ZoneID *terraformWriter.Literal `cty:"zone_id"`
VPCID *terraformWriter.Literal `cty:"vpc_id"`
Lifecycle *terraform.Lifecycle `cty:"lifecycle"`
}View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the IAM policy grants route53:AssociateVPCWithHostedZone on the zone
- Confirm the hosted zone ID in the cluster spec points to a private zone in the same account as the VPC
- Check the VPC ID and region in the cluster spec match an existing VPC
- Run with klog V(2) to see the underlying AWS error detail and act on it
Example fix
// before (IAM policy missing route53:AssociateVPCWithHostedZone)
{"Effect":"Deny","Action":["route53:ChangeResourceRecordSets"],"Resource":"*"}
// after
{"Effect":"Allow","Action":["route53:AssociateVPCWithHostedZone","route53:ChangeResourceRecordSets"],"Resource":"*"} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check zone and permissions
svc := route53.NewFromClient(cfg)
zone, err := svc.GetHostedZone(ctx, &route53.GetHostedZoneInput{Id: aws.String(zoneID)})
if err != nil { return err }
if zone.HostedZone.Config == nil || !aws.ToBool(zone.HostedZone.Config.PrivateZone) {
return fmt.Errorf("zone %s is not private", zoneID)
} Type guard
func isAssociationErr(err error) bool { return err != nil && strings.Contains(err.Error(), "AssociateVPCWithHostedZone") } Try / catch
_, err := cloud.Route53().AssociateVPCWithHostedZone(ctx, request)
if err != nil {
var opErr *smithy.OperationError
if errors.As(err, &opErr) { klog.Errorf("route53 op failed: %v", opErr.Unwrap()) }
return fmt.Errorf("error associating VPC with hosted zone %q: %w", name, err)
} Prevention
- Ensure IAM includes route53:AssociateVPCWithHostedZone
- Confirm the zone is private before relying on VPC association
- Match the VPC region/account with the zone's account
When it happens
Trigger: RenderAWS on a private DNSZone when changes.PrivateVPC is set and the AssociateVPCWithHostedZone call returns an error — e.g. wrong hosted zone ID, zone not actually private, VPC ID/region mismatch, or IAM permissions missing route53:AssociateVPCWithHostedZone.
Common situations: Creating/updating private clusters where the hosted zone was pre-created externally with a different VPC association; credentials lacking Route53 permissions; zone hosted in a different region account than the VPC.
Related errors
- error applying DNS changeset for zone %s: %v
- DNS ZoneID not set
- error deleting route53 record %q: %v
- error querying for route53 zones: %w
- error listing DNS ResourceRecords: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c9e72f3f0a418fc1.
Report an issue: GitHub.