kubernetes/kops · error

error creating gcp machine template: %w

Error message

error creating gcp machine template: %w

What it means

MachineDeploymentBuilder.BuildObjects wraps any failure from createGCPMachineTemplate with this message. That function builds a GCPMachineTemplate unstructured object (infrastructure.cluster.x-k8s.io/v1beta1) including instance type, image, subnet (cluster-suffixed), and network tags. The failure cause is preserved via %w.

Source

Thrown at clusterapi/pkg/builders/machinedeploymentbuilder.go:221

			"template": map[string]any{
				"spec": templateSpec,
			},
		},
	}

	u := &unstructured.Unstructured{Object: obj}

	b.capiInfra = u
	return nil
}

func (b *MachineDeploymentBuilder) BuildObjects(ctx context.Context) ([]*unstructured.Unstructured, error) {
	if err := b.createKopsConfigTemplate(ctx); err != nil {
		return nil, fmt.Errorf("error creating kops config template: %w", err)
	}

	if err := b.createGCPMachineTemplate(ctx); err != nil {
		return nil, fmt.Errorf("error creating gcp machine template: %w", err)
	}

	if err := b.buildMachineDeployments(); err != nil {
		return nil, fmt.Errorf("error building machine deployments: %w", err)
	}

	var objects []*unstructured.Unstructured
	objects = append(objects, b.capiConfigTemplate)
	objects = append(objects, b.capiInfra)

	var machineDeployments []*unstructured.Unstructured
	for _, md := range b.capiMachineDeployments {
		machineDeployments = append(machineDeployments, md)
	}
	sort.Slice(machineDeployments, func(i, j int) bool {
		return machineDeployments[i].GetName() < machineDeployments[j].GetName()
	})

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped underlying error after this message for the actual cause.
  2. Validate ClusterName (must survive gce.SafeClusterName / 63-char suffixing) and Subnet before building.
  3. Ensure Role is a valid kops.InstanceGroupRole (e.g. Node, ControlPlane) so TagForRole can compute the network tag.
  4. Check the Image field format; values with one '/' are rewritten to projects/<proj>/global/images/<name>, invalid forms pass through and may fail downstream.

Example fix

// before
b := &builders.MachineDeploymentBuilder{ClusterName: "", Subnet: ""}
// after
if b.ClusterName == "" || b.Subnet == "" {
    return fmt.Errorf("ClusterName and Subnet are required")
}
Defensive patterns

Strategy: validation

Validate before calling

if b.ClusterName == "" || len(b.ClusterName) > 63 {
    return fmt.Errorf("ClusterName must be non-empty and <= 63 chars")
}
if b.Subnet == "" {
    return fmt.Errorf("Subnet must be set")
}
if b.Role == "" {
    return fmt.Errorf("Role must be a valid kops.InstanceGroupRole")
}

Try / catch

objs, err := builder.BuildObjects(ctx)
if err != nil {
    var wrapped error
    if errors.As(err, &wrapped) && strings.Contains(err.Error(), "gcp machine template") {
        return fmt.Errorf("GCPMachineTemplate generation failed (check cluster name/subnet/role): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling BuildObjects when createGCPMachineTemplate errors — e.g. gce.TagForRole or gce.ClusterSuffixedName helpers failing on malformed ClusterName/Subnet/Role inputs, or a dead context.

Common situations: Cluster names exceeding GCP's 63-char safe-name limit, an empty or unrecognized InstanceGroupRole, an empty Subnet producing an invalid suffixed name, or a malformed image spec.

Related errors


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