kubernetes/kops · error

failed to create bootstrap data secret for KopsConfig %s/%s:

Error message

failed to create bootstrap data secret for KopsConfig %s/%s: %w

What it means

storeBootstrapData creates a Secret (same name/namespace as the KopsConfig) holding the nodeup bootstrap script, after confirming no such secret exists. This error wraps a failure of the Secret Create call — RBAC denial, quota/limits, validation, or the secret appearing concurrently (AlreadyExists races through a NotFound Get).

Source

Thrown at pkg/controllers/clusterapi/kopsconfig_controller.go:158

		Type: clusterv1.ClusterSecretType,
	}

	parentAPIVersion, parentKind := parent.GetObjectKind().GroupVersionKind().ToAPIVersionAndKind()
	secret.OwnerReferences = []metav1.OwnerReference{
		{
			APIVersion: parentAPIVersion,
			Kind:       parentKind,
			Name:       parent.GetName(),
			UID:        parent.GetUID(),
			Controller: pointer.Bool(true),
		},
	}

	var existing corev1.Secret
	if err := r.client.Get(ctx, secretName, &existing); err != nil {
		if apierrors.IsNotFound(err) {
			if err := r.client.Create(ctx, secret); err != nil {
				return fmt.Errorf("failed to create bootstrap data secret for KopsConfig %s/%s: %w", parent.GetNamespace(), parent.GetName(), err)
			}
		} else {
			return fmt.Errorf("failed to get bootstrap data secret: %w", err)
		}
	} else {
		// TODO: Verify that the existing secret "matches"
		klog.Warningf("TODO: verify that the existing secret matches our expected value")
	}

	parent.Status.DataSecretName = pointer.String(secret.Name)
	parent.Status.Ready = true
	// conditions.MarkTrue(scope.Config, bootstrapv1.DataSecretAvailableCondition)
	return nil
}

func (r *KopsConfigReconciler) buildBootstrapData(ctx context.Context, cluster *kopsapi.Cluster, kopsControlPlane *capikops.KopsControlPlane) ([]byte, error) {
	wellKnownAddresses := model.WellKnownAddresses{}
	for _, systemEndpoint := range kopsControlPlane.Status.SystemEndpoints {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Grant RBAC create on secrets to the controller ServiceAccount
  2. Handle AlreadyExists gracefully: treat a concurrent create as success and proceed to set the status
  3. Check namespace ResourceQuotas and LimitRanges for secret count/size constraints
  4. Inspect the wrapped error to distinguish Forbidden vs AlreadyExists vs validation
  5. Retry the reconcile — the next pass will find the existing secret via the Get

Example fix

// before
if err := r.client.Create(ctx, secret); err != nil {
    return fmt.Errorf("failed to create bootstrap data secret for KopsConfig %s/%s: %w", parent.GetNamespace(), parent.GetName(), err)
}
// after: tolerate the create/get race
if err := r.client.Create(ctx, secret); err != nil {
    if !apierrors.IsAlreadyExists(err) {
        return fmt.Errorf("failed to create bootstrap data secret for KopsConfig %s/%s: %w", parent.GetNamespace(), parent.GetName(), err)
    }
}
Defensive patterns

Strategy: retry

Validate before calling

kubectl auth can-i create secrets -n <namespace> --as=system:serviceaccount:<ns>:<sa>
kubectl get resourcequota -n <namespace>

Try / catch

if err := r.client.Create(ctx, secret); err != nil {
    if apierrors.IsAlreadyExists(err) {
        return nil // concurrent reconcile won the race; proceed to status update
    }
    return fmt.Errorf("failed to create bootstrap data secret for KopsConfig %s/%s: %w", parent.GetNamespace(), parent.GetName(), err)
}

Prevention

When it happens

Trigger: r.client.Create fails because the controller ServiceAccount lacks create permission on secrets; the namespace has a resource quota or Secret count limit; a concurrent reconcile created the secret between the Get (NotFound) and Create (AlreadyExists); the API server rejects the object (too large, invalid ownerRef).

Common situations: Fresh installs with incomplete RBAC; rapid re-reconciles racing to create the same secret; namespaces enforcing quotas on secret count or size; very large bootstrap scripts hitting etcd object limits.

Related errors


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