{"record":{"id":"a9ec1525a78fb17b","repo":"k3s-io/k3s","slug":"no-bootstrap-data-is-available-to-reconcile-agains","errorCode":null,"errorMessage":"no bootstrap data is available to reconcile against","messagePattern":"no bootstrap data is available to reconcile against","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/cluster/bootstrap.go","lineNumber":338,"sourceCode":"\n\t\tkv, c.saveBootstrap, err = getBootstrapKeyFromStorage(ctx, storageClient, normalizedToken, token)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif kv == nil || len(kv.Value) == 0 {\n\t\t\treturn errors.New(\"no bootstrap data found in datastore - check server token value and verify datastore integrity\")\n\t\t}\n\n\t\tdbRawData, err := decrypt(normalizedToken, kv.Value)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tbuf = bytes.NewReader(dbRawData)\n\t}\n\n\tif buf == nil {\n\t\treturn errors.New(\"no bootstrap data is available to reconcile against\")\n\t}\n\n\tpaths, err := bootstrap.ObjToMap(crb)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfiles := make(bootstrap.PathsDataformat)\n\tif !isMigrated(buf, &files) {\n\t\tif err := migrateBootstrapData(ctx, buf, files); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbuf.Seek(0, 0)\n\t}\n\n\t// Compare on-disk content to the datastore.\n\t// If the files differ and the timestamp in the datastore is newer, data on disk will be updated.\n\t// If the files differ and the timestamp on disk is newer, an error will be raised listing the conflicting files.","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/cluster/bootstrap.go#L320-L356","documentation":"Emitted at the end of the reconcile bootstrap path when 'buf' is still nil: neither the HTTP-join branch (fetching bootstrap from an existing server) nor the managed-datastore branch (decrypting the '/bootstrap' key) produced a bootstrap payload. It means the server has no source of truth for its control-plane state and cannot continue.","triggerScenarios":"Server configured neither to initialize a new datastore nor able to read one: managedDB path ran but returned nil kv without erroring earlier is impossible here, so this fires when the function is reached without any managed DB and without a successful HTTP bootstrap fetch (join URL unreachable, or storageBootstrap path skipped).","commonSituations":"Fresh data-dir with no --cluster-init and no reachable --server join URL; join URL points to a peer that is itself not ready; misconfigured DataDir so prior bootstrap files are absent.","solutions":["If this is the first server, start it with --cluster-init (or point at an existing datastore) so bootstrap data is created.","If joining, verify the --server URL is reachable (https://<ip>:6443/ping) and that the supervisor on the peer is fully started, then restart this node.","Check that DataDir was not changed between restarts, wiping the token/bootstrap files; restore or reinitialize as appropriate."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before start: require either an initialized datastore or a reachable join server.\nfunc canBootstrap(dataDir string, joinURL string) error {\n\tif _, err := os.Stat(filepath.Join(dataDir, \"db\")); err == nil {\n\t\treturn nil // existing datastore\n\t}\n\tif joinURL == \"\" {\n\t\treturn errors.New(\"no datastore and no --server join URL: bootstrap impossible; use --cluster-init\")\n\t}\n\tresp, err := http.Get(joinURL + \"/ping\")\n\tif err != nil || resp.StatusCode != http.StatusOK {\n\t\treturn errors.New(\"join server not reachable: \" + joinURL)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := startServer(); err != nil {\n\tif strings.Contains(err.Error(), \"no bootstrap data is available to reconcile against\") {\n\t\t// fatal config: fix --cluster-init / --server / data-dir then relaunch\n\t}\n}","preventionTips":["First server in every cluster: always pass --cluster-init (or an external datastore endpoint).","Automate a connectivity preflight (GET /ping) to the join server before starting a joining node.","Never change --data-dir between restarts without migrating the db directory."],"tags":["k3s","bootstrap","startup","join"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}