kubernetes/kops · error
failed to get bootstrap data secret: %w
Error message
failed to get bootstrap data secret: %w
What it means
This error wraps any failure from the controller-runtime client Get when reading the bootstrap-data Secret named after the KopsConfig object (pkg/controllers/clusterapi/kopsconfig_controller.go:155-161). It is thrown only when the Get fails for a reason OTHER than NotFound (NotFound is handled by creating the secret instead), so it indicates the API server rejected or failed the read. The controller cannot proceed to store bootstrap data, and Reconcile returns the error to trigger a retry with backoff.
Source
Thrown at pkg/controllers/clusterapi/kopsconfig_controller.go:161
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 {
switch systemEndpoint.Type {
case capikops.SystemEndpointTypeKopsController:
wellKnownAddresses[wellknownservices.KopsController] = append(wellKnownAddresses[wellknownservices.KopsController], systemEndpoint.Endpoint)View on GitHub (pinned to 4c8573c808)
Solutions
- Check RBAC: ensure the controller's ServiceAccount has get/list on secrets in the KopsConfig namespace (see the +kubebuilder:rbac markers; verify with kubectl auth can-i get secrets --as=system:serviceaccount:<ns>:<sa>).
- Check API server health and connectivity from the controller pod (kubectl get --raw /healthz from an exec, or inspect controller logs for connection refused/timeout).
- Inspect the wrapped error text after 'failed to get bootstrap data secret:' to identify the exact cause (forbidden vs timeout vs context canceled).
- If errors are transient (timeouts), they will be retried by controller-runtime; verify the error clears rather than modifying data.
- If a mutating admission webhook intercepts Secrets, verify it is not rejecting or delaying GET-related operations and is reachable.
Example fix
// before: controller RBAC missing secrets read // (manifest omits ClusterRole rule) // after rules: - apiGroups: [""] resources: ["secrets"] verbs: ["create", "get", "list", "watch", "patch", "update"]
Defensive patterns
Strategy: try-catch
Validate before calling
// Go: pre-check secret read access before relying on the controller
err := r.client.Get(ctx, secretName, &existing)
if err != nil && !apierrors.IsNotFound(err) {
// surface wrapped cause early
}
// CLI RBAC pre-check:
// kubectl auth can-i get secret <name> -n <ns> --as=system:serviceaccount:<ns>:<sa> Type guard
// Go: classify the error before reacting
func isRealSecretError(err error) bool {
return err != nil && !apierrors.IsNotFound(err) // NotFound is handled by Create path
} Try / catch
if err := r.storeBootstrapData(ctx, obj, data); err != nil {
if apierrors.IsForbidden(err) {
// fix RBAC (RoleBinding) rather than retrying
return ctrl.Result{}, fmt.Errorf("fix secrets RBAC: %w", err)
}
// transient API server errors: let controller-runtime retry with backoff
return ctrl.Result{}, err // requeue
} Prevention
- Ship the kubebuilder-generated ClusterRole with secrets get/create/update permissions and keep it in sync with code markers.
- Monitor controller logs for 'failed to get bootstrap data secret' and alert on non-NotFound variants.
- Verify API server health and network policy between controller pod and API server before deploying.
- Run the controller with a dedicated ServiceAccount and validate its permissions in CI (kubectl auth can-i).
- Avoid admission webhooks on Secret GET paths that could block controller reads.
When it happens
Trigger: The Get of Secret <namespace>/<kopsconfig-name> fails with a non-NotFound error: RBAC denial (no get permission on secrets), API server connection errors/timeouts, the secret exists but cannot be read (e.g. too large, corrupted), context cancellation during reconcile, or webhook/authorizer failures.
Common situations: Operators deploying the kops cluster-api controllers without the kubebuilder-generated RBAC for secrets; an API server outage or network partition in the management cluster; reconcile running with an expired or revoked service-account token; a security policy (e.g. PSA restricted, admission webhook) blocking secret reads.
Related errors
- applying kubeconfig secret to cluster: %w
- failed to create bootstrap data secret for KopsConfig %s/%s:
- error adding needs-update label: %v
- error applying annotation to record addon installation: %v
- error querying namespace %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/fa1c24d655d9704b.
Report an issue: GitHub.