{"record":{"id":"93de1cd1a8c86d81","repo":"k3s-io/k3s","slug":"node-password-rejected-duplicate-hostname-or-cont","errorCode":null,"errorMessage":"Node password rejected, duplicate hostname or contents of '%s' may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag","messagePattern":"Node password rejected, duplicate hostname or contents of '(.+?)' may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/agent/config/config.go","lineNumber":180,"sourceCode":"\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\t// If we got a 401 Unauthorized response when using client certs, try again without client cert auth.\n\t\t// This allows us to fall back from node identity to token when the node resource is deleted.\n\t\tif resp.StatusCode == http.StatusUnauthorized {\n\t\t\tif transport, ok := client.Transport.(*http.Transport); ok && transport.TLSClientConfig != nil && len(transport.TLSClientConfig.Certificates) != 0 {\n\t\t\t\tlogrus.Infof(\"Node authorization rejected, retrying without client certificate authentication\")\n\t\t\t\ttransport.TLSClientConfig.Certificates = []tls.Certificate{}\n\t\t\t\tresp, err = client.Do(req)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tdefer resp.Body.Close()\n\t\t\t}\n\t\t}\n\n\t\tif resp.StatusCode == http.StatusForbidden {\n\t\t\treturn nil, fmt.Errorf(\"Node password rejected, duplicate hostname or contents of '%s' may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag\", nodePasswordFile)\n\t\t}\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\treturn nil, fmt.Errorf(\"%s: %s\", u, resp.Status)\n\t\t}\n\n\t\treturn io.ReadAll(resp.Body)\n\t}\n}\n\nfunc ensureNodeID(nodeIDFile string) (string, error) {\n\tif _, err := os.Stat(nodeIDFile); err == nil {\n\t\tid, err := os.ReadFile(nodeIDFile)\n\t\treturn strings.TrimSpace(string(id)), err\n\t}\n\tid := make([]byte, 4, 4)\n\t_, err := cryptorand.Read(id)\n\tif err != nil {","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/agent/config/config.go#L162-L198","documentation":"When the agent fetches its configuration from the server over HTTP and gets 403 Forbidden (after the built-in retry without client-certificate auth), this error is returned: the node password stored at nodePasswordFile does not match the server's node-passwd entry for that node name. It usually means another machine with the same hostname registered first, or this node's password file was regenerated while the server still holds the old entry.","triggerScenarios":"GET to the agent config URL returns 403: duplicate NODE_NAME in the cluster, cloned VMs reusing a hostname, or the node's /etc/rancher/node/password file recreated (data-dir wiped) while the Node object persists server-side.","commonSituations":"Cloning VM templates without changing hostnames; re-provisioning nodes with the same name; hostname collisions from DHCP/DNS; reinstalling the OS without deleting the old Node object.","solutions":["Start the agent with --with-node-id to append a generated unique id to the node name (the remediation the error text itself suggests)","Delete the stale node so it can re-register: kubectl delete node <hostname>","Ensure every node has a unique hostname before joining","If the node was reinstalled, drain and delete the old entry first, then rejoin"],"exampleFix":"# before\nk3s agent --server https://server:6443 --token mynodetoken\n\n# after (cloned/duplicate hostnames)\nk3s agent --server https://server:6443 --token mynodetoken --with-node-id","handlingStrategy":"validation","validationCode":"# before joining, ensure no live Node already owns this hostname:\nhostname=$(hostname)\nif kubectl get node \"$hostname\" >/dev/null 2>&1; then\n    echo \"node name collision: delete the old node or use --with-node-id\"\nfi","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"Node password rejected\") {\n    // operational remediation, not a retry: either kubectl delete node <hostname>\n    // or restart the agent with --with-node-id for duplicate hostnames\n}","preventionTips":["Assign unique hostnames at image/provisioning time (cloud-init, kickstart)","For cloned VMs, always start agents with --with-node-id","When reinstalling a node, drain and delete its Node object first"],"tags":["auth","node","registration","cluster","hostname"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}