kubernetes/kops · error
error converting nodeup config to yaml: %w
Error message
error converting nodeup config to yaml: %w
What it means
GetBootstrapData serializes the fully remapped nodeup config (the per-instance-group NodeUpConfig) to YAML so it can be staged on the node's local filesystem. yaml.Marshal of nodeupConfig virtually never fails for well-formed structs; if it does, this wrapper reports the failure and aborts bootstrap data generation.
Source
Thrown at pkg/commands/toolbox_enroll.go:974
)
if err != nil {
return nil, fmt.Errorf("rewriting channels manifest: %w", err)
}
bootstrapData.NodeupScriptAdditionalFiles[nodeupConfig.ChannelsManifest] = rewritten
}
if nodeupConfig.ConfigStore != nil {
if err := remapTree(&nodeupConfig.ConfigStore.Keypairs, path.Join(targetDir, "pki/etcd")); err != nil {
return nil, err
}
if err := remapTree(&nodeupConfig.ConfigStore.Secrets, path.Join(targetDir, "pki")); err != nil {
return nil, err
}
}
nodeupConfigBytes, err := yaml.Marshal(nodeupConfig)
if err != nil {
return nil, fmt.Errorf("error converting nodeup config to yaml: %w", err)
}
// Not much reason to hash this, since we're reading it from the local file system
// sum256 := sha256.Sum256(nodeupConfigBytes)
// bootConfig.NodeupConfigHash = base64.StdEncoding.EncodeToString(sum256[:])
p := path.Join(targetDir, "igconfig", bootConfig.InstanceGroupRole.ToLowerString(), ig.Name, "nodeupconfig.yaml")
bootstrapData.NodeupScriptAdditionalFiles[p] = nodeupConfigBytes
// Copy any static manifests we need on the control plane
for _, staticManifest := range assetBuilder.StaticManifests() {
if !staticManifest.AppliesToRole(bootConfig.InstanceGroupRole) {
continue
}
p := path.Join(targetDir, staticManifest.Path)
bootstrapData.NodeupScriptAdditionalFiles[p] = staticManifest.Contents
}
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Read the wrapped inner error from the message — it names the offending Go type or cycle; fix that field on NodeUpConfig (or your fork's added fields) to be YAML-serializable.
- If introduced by a dependency upgrade, pin/align k8s.io/apimachinery and sigs.k8s.io/yaml versions (go mod tidy / make gomod) and rebuild.
- Ensure any custom fields added to NodeUpConfig have yaml tags and supported types (string keys in maps, no funcs/channels/cycles).
- Retry on stock (unforked) kops at the cluster's version to confirm the failure is fork/dependency related.
Example fix
// before: unserializable custom field on NodeUpConfig
type NodeUpConfig struct {
ExtraHooks map[net.IP]string `json:"extraHooks,omitempty"`
}
// after: use a string-keyed map
type NodeUpConfig struct {
ExtraHooks map[string]string `json:"extraHooks,omitempty"`
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: ensure the NodeUpConfig can round-trip through YAML before enroll
if _, err := yaml.Marshal(nodeupConfig); err != nil {
return fmt.Errorf("nodeup config not serializable: %w", err)
} Type guard
func yamSerializable(v interface{}) bool {
_, err := yaml.Marshal(v)
return err == nil
} Try / catch
bootstrapData, err := GetBootstrapData(ctx, ...)
if err != nil {
if strings.Contains(err.Error(), "converting nodeup config to yaml") {
// log the wrapped cause naming the offending type, and stop — this is a code/dependency bug, not transient
klog.Fatalf("non-transient serialization failure: %v", err)
}
return err
} Prevention
- Keep NodeUpConfig fields YAML-friendly: string map keys, no funcs/channels/cycles.
- Run unit tests that marshal NodeUpConfig whenever adding fields or bumping apimachinery/sigs.k8s.io/yaml.
- Avoid ad-hoc dependency upgrades in forks; use `make gomod` and the project's pinned versions.
When it happens
Trigger: GetBootstrapData (via getNodeConfig / RunToolboxEnroll / buildBootstrapData) reaching the yaml.Marshal(nodeupConfig) call with a value the yaml encoder cannot represent — e.g. an unsupported type (chan/func/cyclic reference) introduced by custom code or an incompatibility between the vendored k8s.io/apimachinery types and the sigs.k8s.io/yaml encoder after a dependency upgrade.
Common situations: Custom kops forks adding fields with non-serializable types to NodeUpConfig; dependency bumps (gopkg.in/yaml.v2/v3 vs sigs.k8s.io/yaml) changing marshal semantics; maps with non-string keys added to the config struct.
Related errors
- error marshaling manifest to yaml: %w
- error marshaling %s to yaml: %v
- marshalling nodeupConfig: %w
- error marshaling yaml: %v
- error writing yaml to stdout: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/6281464cd44e807c.
Report an issue: GitHub.