kubernetes/kops · critical

error parsing NodeupConfig

Error message

error parsing NodeupConfig %q: %v

What it means

nodeup reads the cluster's NodeupConfig YAML from the state store (configBase/igconfig/<role>/<instancegroup>/nodeupconfig.yaml) and unmarshals it into nodeup.Config. This error means the file was fetched successfully but utils.YamlUnmarshal could not parse it into the Config struct — the YAML is malformed or its fields don't match the expected schema. It is thrown during NodeUpCommand.Run, before any provisioning work happens.

Solutions

  1. Fetch the exact file shown in the error and validate it: kops toolbox dump won't help — instead download it (e.g. aws s3 cp s3://<statestore>/cluster/igconfig/<role>/<ig>/nodeupconfig.yaml -) and run it through a YAML linter / yaml.Unmarshal to spot syntax or type problems.
  2. Check the kOps version that wrote the state store versus the nodeup binary version; mismatched schemas cause unmarshal failures. Upgrade nodeup/kops so both use the same Config schema, or re-run 'kops update cluster' to regenerate the config.
  3. Regenerate and push the cluster configuration with 'kops update cluster' (then 'kops rolling-update cluster' as needed) so a known-good nodeupconfig.yaml is written to the state store.
  4. As a last resort, restore the file from the state store backup or re-create the instance group ('kops replace -f ig.yaml') to rewrite nodeupconfig.yaml.

Example fix

// before: hand-edited nodeupconfig.yaml with a tab character
	configStore:
		secrets: s3://bucket/secrets
// after: use spaces only and valid types
configStore:
  secrets: s3://bucket/secrets
Defensive patterns

Strategy: validation

Validate before calling

// Validate nodeupconfig.yaml parses before invoking nodeup
b, err := os.ReadFile("nodeupconfig.yaml")
if err != nil { return err }
var cfg nodeup.Config
if err := yaml.Unmarshal(b, &cfg); err != nil {
    return fmt.Errorf("nodeupconfig.yaml is invalid: %w", err)
}

Try / catch

err := cmd.Run(out)
if err != nil && strings.Contains(err.Error(), "error parsing NodeupConfig") {
    // inspect the yaml file at the reported path and fix syntax/schema
}

Prevention

When it happens

Trigger: Calling NodeUpCommand.Run() with bootConfig.InstanceGroupName set (VFS path, not config-server path) where the nodeupconfig.yaml at the joined VFS path contains invalid YAML (bad indentation, tabs, duplicate keys) or fields with wrong types (e.g. a string where nodeup.Config expects a bool/int/map), or the file was written by an incompatible kOps version.

Common situations: Hand-edited nodeupconfig.yaml in the state store; partial/truncated upload to S3/GCS/object storage; state store produced by a newer or older kOps version whose Config schema differs; corruption in the object store serving the file.

Related errors


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

Appendix: source

Thrown at upup/pkg/fi/nodeup/command.go:154

	case nodeConfig != nil:
		if err := utils.YamlUnmarshal([]byte(nodeConfig.NodeupConfig), &nodeupConfig); err != nil {
			return fmt.Errorf("error parsing BootConfig config response: %v", err)
		}
		nodeupConfigHash = sha256.Sum256([]byte(nodeConfig.NodeupConfig))
		if nodeupConfig.CAs == nil {
			nodeupConfig.CAs = make(map[string]string)
		}
		nodeupConfig.CAs[fi.CertificateIDCA] = bootConfig.ConfigServer.CACertificates
	case bootConfig.InstanceGroupName != "":
		nodeupConfigLocation := configBase.Join("igconfig", bootConfig.InstanceGroupRole.ToLowerString(), bootConfig.InstanceGroupName, "nodeupconfig.yaml")

		b, err := nodeupConfigLocation.ReadFile(ctx)
		if err != nil {
			return fmt.Errorf("error loading NodeupConfig %q: %v", nodeupConfigLocation, err)
		}

		if err = utils.YamlUnmarshal(b, &nodeupConfig); err != nil {
			return fmt.Errorf("error parsing NodeupConfig %q: %v", nodeupConfigLocation, err)
		}
		nodeupConfigHash = sha256.Sum256(b)
	default:
		return fmt.Errorf("no instance group defined in nodeup config")
	}

	if bootConfig.NodeupConfigHash != "" {
		if want, got := bootConfig.NodeupConfigHash, base64.StdEncoding.EncodeToString(nodeupConfigHash[:]); got != want {
			return fmt.Errorf("nodeup config hash mismatch (was %q, expected %q)", got, want)
		}
	}

	err = evaluateSpec(&nodeupConfig, bootConfig.CloudProvider, region)
	if err != nil {
		return err
	}

	architecture, err := architectures.FindArchitecture()

View on GitHub (pinned to 4c8573c808)