kubernetes/kops · error
error creating Router: %w
Error message
error creating Router: %w
What it means
This error is returned by the GCE Router task's RenderGCE when the google Compute API call Routers().Insert() fails while kOps tries to create a Cloud Router (used for Cloud NAT) in the target project/region. It wraps the underlying Google API error, so the root cause (quota, permission, invalid config, API error) is in the wrapped %w error. It means the router resource was never created and the apply of this task failed.
Source
Thrown at upup/pkg/fi/cloudup/gcetasks/router.go:173
Network: e.Network.URL(project),
Nats: []*compute.RouterNat{
{
Name: *e.Name,
NatIpAllocateOption: *e.NATIPAllocationOption,
SourceSubnetworkIpRangesToNat: *e.SourceSubnetworkIPRangesToNAT,
},
},
}
for _, subnet := range e.Subnetworks {
router.Nats[0].Subnetworks = append(router.Nats[0].Subnetworks, &compute.RouterNatSubnetworkToNat{
Name: subnet.URL(project, region),
SourceIpRangesToNat: []string{subnetNatAllIPRanges},
})
}
op, err := t.Cloud.Compute().Routers().Insert(project, region, router)
if err != nil {
return fmt.Errorf("error creating Router: %w", err)
}
if err := t.Cloud.WaitForOp(op); err != nil {
return fmt.Errorf("error waiting for router creation: %w", err)
}
} else {
if !reflect.DeepEqual(changes, &Router{}) {
return fmt.Errorf("applying changes to Router is unsupported: %s", *e.Name)
}
}
return nil
}
type terraformRouterNat struct {
Name *string `cty:"name"`
Region *string `cty:"region"`
Router *terraformWriter.Literal `cty:"router"`
NATIPAllocateOption *string `cty:"nat_ip_allocate_option"`View on GitHub (pinned to 4c8573c808)
Solutions
- Read the wrapped error in the message for the exact Google API cause (permissionDenied, quotaExceeded, notFound, etc.) and address that first
- Verify the Compute Engine API is enabled in the project (gcloud services list --enabled | grep compute)
- Check the GCE service account has roles/compute.networkAdmin or at least compute.routers.create permission
- Confirm the cluster spec's region/network/subnet names are correct and exist in the project
- Retry the `kops update cluster` apply if the underlying error was transient (rate limit / backend error)
Example fix
// before (transient API failures abort the apply)
op, err := t.Cloud.Compute().Routers().Insert(project, region, router)
if err != nil {
return fmt.Errorf("error creating Router: %w", err)
}
// after (retry transient errors with backoff before giving up)
op, err := t.Cloud.Compute().Routers().Insert(project, region, router)
if err != nil {
if gce.IsRetryable(err) {
return fi.NewRetryableError(fmt.Errorf("error creating Router: %w", err))
}
return fmt.Errorf("error creating Router: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check before apply
if err := checkComputeAPIEnabled(projectID); err != nil { return err }
if _, err := compute.Routers.List(projectID, region).Do(); err != nil {
return fmt.Errorf("cannot access Routers API in %s: %w", region, err)
} Type guard
func isPermissionDenied(err error) bool {
var ge *googleapi.Error
return errors.As(err, &ge) && (ge.Code == 403 || ge.Code == 401)
} Try / catch
op, err := cloud.Compute().Routers().Insert(project, region, router)
if err != nil {
var ge *googleapi.Error
if errors.As(err, &ge) && ge.Code == 403 {
return fmt.Errorf("missing compute.routers.create permission: %w", err)
}
return fmt.Errorf("error creating Router: %w", err)
}
if err := cloud.WaitForOp(op); err != nil {
return fmt.Errorf("error waiting for router creation: %w", err)
} Prevention
- Enable the Compute Engine API in the project before running kops
- Grant the kOps service account compute.networkAdmin
- Validate region/network/subnet names in the cluster spec before apply
- Retry applies on transient Google API 5xx errors
When it happens
Trigger: Routers().Insert(project, region, router) returns a non-nil error during `kops update cluster` on GCE: e.g. the compute API is disabled, the service account lacks compute.routers.create, the region is wrong, a router with the same name exists in a conflicting state, or quota/billing issues.
Common situations: New GCE projects where the Compute Engine API was just enabled and propagation is pending; IAM scopes on the node/service account missing compute rights; deploying to a region typo'd in the cluster spec; Google API transient 5xx/rate-limit errors during cluster creation.
Related errors
- error waiting for router creation: %w
- applying changes to Router is unsupported: %s
- error fetching GCE instance: %w
- error fetching GCE instance group template %q: %v
- error fetching GCE managed instance group %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/c4c3a6047063a05c.
Report an issue: GitHub.