rancher/rancher · error

no config content

Error message

no config content

What it means

connectConfigYaml scans the plan's files array for the entry whose path equals planner.ConfigYamlFileName for the detected runtime (rke2 vs k3s) and takes its content. If no entry matches, or the matched entry's content is empty, it returns the fixed 500 'no config content' - the plan did not include the runtime config file the server expected.

Source

Thrown at pkg/capr/configserver/server.go:237

	kubernetesVersion, err := r.getClusterKubernetesVersion(mpSecret.Labels[capi.ClusterNameLabel], ns)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
		return
	}

	var content string
	for _, f := range config["files"].([]interface{}) {
		f := f.(map[string]interface{})
		if path, ok := f["path"].(string); ok && path == fmt.Sprintf(planner.ConfigYamlFileName, capr.GetRuntime(kubernetesVersion)) {
			if _, ok := f["content"]; ok {
				content = f["content"].(string)
			}
		}
	}

	if content == "" {
		http.Error(rw, "no config content", http.StatusInternalServerError)
		return
	}

	jsonContent, err := base64.StdEncoding.DecodeString(content)
	if err != nil {
		http.Error(rw, err.Error(), http.StatusInternalServerError)
		return
	}

	rw.Header().Set("Content-Type", "application/json")
	_, _ = rw.Write(jsonContent)
}

func (r *RKE2ConfigServer) connectClusterInfo(secret *corev1.Secret, rw http.ResponseWriter, req *http.Request) {
	headers := dataFromHeaders(req)

	// expecting -H "X-Cattle-Field: kubernetesversion" -H "X-Cattle-Field: name"
	fields, ok := headers["field"]

View on GitHub (pinned to 932558d4e6)

Solutions

  1. Inspect the files: kubectl ... | jq -r '.files[].path' and confirm the runtime-specific config file exists with non-empty content.
  2. Regenerate the plan (delete the plan secret / re-plan the machine) so the planner injects the config file.
  3. Verify the cluster's kubernetesVersion resolves - the expected filename depends on GetRuntime(version).
  4. If using custom plan templates, add the expected config file entry with content.
Defensive patterns

Strategy: validation

Validate before calling

kubectl -n <ns> get secret <name> -o jsonpath='{.data.rolePlan}' | base64 -d | jq '[.files[].path] | map(select(contains("config.yaml")))' # must list the runtime config file

Type guard

func hasRuntimeConfig(files []interface{}, runtime string) bool {
	want := fmt.Sprintf(planner.ConfigYamlFileName, runtime)
	for _, f := range files {
		m, ok := f.(map[string]interface{})
		if !ok { continue }
		if p, _ := m["path"].(string); p == want {
			if c, _ := m["content"].(string); c != "" { return true }
		}
	}
	return false
}

Try / catch

if content == "" { trigger re-plan; do not fabricate a config; alert on plan-generation regression }

Prevention

When it happens

Trigger: A plan whose files list omits the runtime config file (for example /etc/rancher/rke2/config.yaml.d/50-rancher.yaml or the k3s equivalent), or whose matching entry has empty content; runtime detection disagreeing with what was planned when kubernetesVersion cannot be resolved.

Common situations: Custom plan templates built without the rancher config file; version skew changing the expected filename; plans for machines whose version label is missing so GetRuntime falls back unexpectedly.

Related errors


AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16). Data as JSON: /api/errors/ec078fe178f32c2a. Report an issue: GitHub.