kubernetes/kops · error
bootstrapping node labels: %w
Error message
bootstrapping node labels: %w
What it means
When --node-name is set, runApplyChannelIteration calls nodelabeler.BootstrapControlPlaneNodeLabels to patch the named node with the given labels. Any failure from that call (node not found, API error, patch rejected) is wrapped with this message and merged into the multierr, so the channel apply still proceeds but the error is reported.
Source
Thrown at channels/pkg/cmd/apply_channel.go:111
labels[pair[0]] = pair[1]
} else {
labels[rawpair] = ""
}
}
return labels, nil
}
// runApplyChannelIteration patches node labels (when --node-name is set) then
// applies the channel. Labels go first so addons targeting the control-plane
// label can schedule on the local node as soon as their manifests land.
func runApplyChannelIteration(ctx context.Context, f *ChannelsFactory, out io.Writer, options *ApplyChannelOptions, args []string) error {
var merr error
if options.NodeName != "" {
labelerClient, err := f.KubernetesClient()
if err != nil {
merr = multierr.Append(merr, fmt.Errorf("building kubernetes client for node labeler: %w", err))
} else if err := nodelabeler.BootstrapControlPlaneNodeLabels(ctx, labelerClient, options.NodeName, options.NodeLabels); err != nil {
merr = multierr.Append(merr, fmt.Errorf("bootstrapping node labels: %w", err))
}
}
if err := RunApplyChannel(ctx, f, out, options, args); err != nil {
merr = multierr.Append(merr, err)
}
return merr
}
// runApplyChannelLoop reconciles repeatedly until ctx is cancelled. A fresh
// ChannelsFactory per iteration drops cached REST configs and the discovery
// cache, picking up cert rotation and new CRDs without a restart.
func runApplyChannelLoop(ctx context.Context, out io.Writer, options *ApplyChannelOptions, args []string) error {
// In daemon mode kops-channels runs as a system-node-critical static pod; serve a
// readiness probe reporting the last apply outcome, so a persistent failure surfaces
// as NotReady (failing `kops validate cluster`, which gates rolling updates) instead
// of only being logged. Starts NotReady until the first successful apply.
readiness, err := serveReadiness(ctx)
if err != nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the node exists: `kubectl get node <node-name>` and that --node-name matches exactly
- Check RBAC allows patch/update on nodes for the channels identity
- Retry after the control plane is ready; the daemon loop retries automatically
- Validate label key/value syntax conforms to Kubernetes label constraints
Defensive patterns
Strategy: retry
Validate before calling
// Go: confirm the node exists and is Ready before labeling
n, err := clientset.CoreV1().Nodes().Get(ctx, nodeName, metav1.GetOptions{})
if err != nil || !isNodeReady(n) {
return fmt.Errorf("node %s not ready for labeling", nodeName)
} Try / catch
err := runApplyChannelIteration(ctx, f, out, options, args)
if err != nil && strings.Contains(err.Error(), "bootstrapping node labels") {
// transient apiserver errors: back off and retry
time.Sleep(5 * time.Second)
return retry(ctx)
} Prevention
- Ensure RBAC grants nodes patch permission to the channels identity
- Keep --node-name in sync with actual node names (downward API metadata.name)
- Treat label bootstrap as idempotent and retriable
- Validate label keys/values before applying
When it happens
Trigger: `kops channels --node-name <node> --node-labels k=v` where the node does not exist, the apiserver rejects the patch (RBAC, conflict), the node is NotReady, or the API request times out.
Common situations: Stale --node-name after node replacement; RBAC denying nodes/status patch for the channels service account; apiserver briefly unavailable during control-plane bootstrap; label keys/values violating Kubernetes label rules.
Related errors
- error adding needs-update label: %v
- error applying annotation to record addon installation: %v
- error querying namespace %q: %v
- error applying annotation to namespace: %v
- failed to apply objects: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5f3e761727171f29.
Report an issue: GitHub.