{"record":{"id":"79091121099a41e6","repo":"k3s-io/k3s","slug":"critical-configuration-value-mismatch-between-serv","errorCode":null,"errorMessage":"critical configuration value mismatch between servers","messagePattern":"critical configuration value mismatch between servers","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cluster/bootstrap.go","lineNumber":558,"sourceCode":"\t\tclusterControl.CriticalControlArgs.EgressSelectorMode = c.config.CriticalControlArgs.EgressSelectorMode\n\t}\n\t// If the remote server is down-level, for secrets-encryption-key-type\n\tif clusterControl.CriticalControlArgs.EncryptProvider == \"\" {\n\t\tclusterControl.CriticalControlArgs.EncryptProvider = c.config.CriticalControlArgs.EncryptProvider\n\t}\n\n\tif diff := deep.Equal(c.config.CriticalControlArgs, clusterControl.CriticalControlArgs); diff != nil {\n\t\trc := reflect.ValueOf(clusterControl.CriticalControlArgs).Type()\n\t\tfor _, d := range diff {\n\t\t\tfield := strings.Split(d, \":\")[0]\n\t\t\tv, _ := rc.FieldByName(field)\n\t\t\tif cliTag, found := v.Tag.Lookup(\"cli\"); found {\n\t\t\t\tlogrus.Warnf(\"critical configuration mismatched: %s\", cliTag)\n\t\t\t} else {\n\t\t\t\tlogrus.Warnf(\"critical configuration mismatched: %s\", field)\n\t\t\t}\n\t\t}\n\t\treturn errors.New(\"critical configuration value mismatch between servers\")\n\t}\n\treturn nil\n}\n\n// ipsTo16Bytes makes sure the IPs in the []*net.IPNet slice are represented in 16-byte format\nfunc ipsTo16Bytes(mySlice []*net.IPNet) {\n\tfor _, ipNet := range mySlice {\n\t\tipNet.IP = ipNet.IP.To16()\n\t}\n}\n","sourceCodeStart":540,"sourceCodeEnd":569,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/cluster/bootstrap.go#L540-L569","documentation":"During join/reconciliation the server deep-compares its config.CriticalControlArgs against CriticalControlArgs stored in the cluster bootstrap. Any diff logs per-field warnings ('critical configuration mismatched: <cli tag>') and returns this error, blocking a server whose fundamental networking/runtime flags disagree with the cluster.","triggerScenarios":"Joining server passes different values for any CriticalControlArgs field (cluster-cidr, service-cidr, cluster-dns, disable-network-policy, flannel backend, etc.) via CLI flags or /etc/rancher/k3s/config.yaml than the values published by the first server.","commonSituations":"Config file copied from a template with a different cluster-cidr; one node got --cluster-dns manually; nodes in the same cluster built from different install scripts or versions where defaults changed.","solutions":["Read the 'critical configuration mismatched: <flag>' warning lines immediately above the error; they name the exact disagreeing flags.","Edit this node's /etc/rancher/k3s/config.yaml or CLI flags so the listed values match the first server exactly.","Restart k3s on this node; if the first server's values were themselves wrong, plan a coordinated cluster reinit instead of divergent flags."],"exampleFix":"# before (joining node)\ncluster-cidr: 10.42.0.0/16\nservice-cidr: 10.43.0.0/16\n# after (match the initiating server)\ncluster-cidr: 10.52.0.0/16\nservice-cidr: 10.53.0.0/16","handlingStrategy":"validation","validationCode":"// Before joining, fetch the cluster's critical args (e.g., from /v1-k3s/config or a config map you publish) and diff:\nfunc criticalArgsCompatible(mine, cluster v1critical.Config) []string {\n\tvar diffs []string\n\tif mine.ClusterCIDR != cluster.ClusterCIDR { diffs = append(diffs, \"cluster-cidr\") }\n\tif mine.ServiceCIDR != cluster.ServiceCIDR { diffs = append(diffs, \"service-cidr\") }\n\tif mine.ClusterDNS != cluster.ClusterDNS { diffs = append(diffs, \"cluster-dns\") }\n\treturn diffs // empty = safe to join\n}","typeGuard":null,"tryCatchPattern":"if err := joinCluster(); err != nil {\n\tif strings.Contains(err.Error(), \"critical configuration value mismatch between servers\") {\n\t\t// read the preceding 'critical configuration mismatched: <flag>' warnings and align config\n\t}\n\treturn err\n}","preventionTips":["Generate all server config.yaml from one template/CMDB so critical flags cannot drift.","Record the first server's cluster-cidr/service-cidr/cluster-dns in inventory and assert on join.","Treat any change to these flags as a cluster reinit, not a per-node edit."],"tags":["k3s","configuration","join","validation","deep-equal"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}