{"record":{"id":"9f37c879880e8094","repo":"k3s-io/k3s","slug":"no-bootstrap-data-found-in-datastore-check-serve","errorCode":null,"errorMessage":"no bootstrap data found in datastore - check server token value and verify datastore integrity","messagePattern":"no bootstrap data found in datastore - check server token value and verify datastore integrity","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/cluster/bootstrap.go","lineNumber":326,"sourceCode":"\t\t\t\tstorageClient = nil\n\t\t\t}\n\t\t}\n\n\t\tif storageClient == nil {\n\t\t\tstorageClient, err = store.NewTemporaryStore(filepath.Join(c.config.DataDir, \"db\", \"etcd\"))\n\t\t\tif err != nil {\n\t\t\t\treturn errors.WithMessage(err, \"failed to create temporary datastore client\")\n\t\t\t}\n\t\t}\n\n\t\tdefer storageClient.Close()\n\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}","sourceCodeStart":308,"sourceCodeEnd":344,"githubUrl":"https://github.com/k3s-io/k3s/blob/6ba341e396edc16b8dcae978a7c5e3ac7ee5606e/pkg/cluster/bootstrap.go#L308-L344","documentation":"Thrown during bootstrap reconciliation when a server using the managed datastore (embedded etcd) retrieved the '/bootstrap' key list but the key selected by getBootstrapKeyFromStorage is nil or has an empty value. The bootstrap key path is '/bootstrap/' + ShortHash(normalizedToken), so the datastore holds no readable bootstrap payload for the supplied token. Without it the server cannot rebuild its CA certs and control-plane runtime.","triggerScenarios":"Restarting a server with a --token different from the one used at cluster creation (hash maps to a nonexistent key path); the on-disk etcd dir (DataDir/db/etcd) being empty or corrupt when opened via NewTemporaryStore after the local etcd connection fails; a datastore restored from a backup that predates the bootstrap write; a key written with an empty value by an interrupted first start.","commonSituations":"K3S_TOKEN rotated or typo'd on restart; data-dir moved, partially wiped, or restored from a stale snapshot; mixing k3s versions where token-hash migration left an empty key; single-server cluster whose db directory was deleted while token file remained.","solutions":["Verify the token matches the original cluster token: compare with /var/lib/rancher/k3s/server/token (or the first server's token file) and restart with that exact value, including the 'K10...' prefix format.","If the token is correct, inspect the datastore: etcdctl get /bootstrap/ --prefix --keys-only and confirm exactly one key exists whose suffix equals the 12-char ShortHash of the normalized token; remove empty or stale keys written under an old token.","If the datastore is empty/corrupt and this was the only server, restore from an etcd snapshot (k3s etcd-snapshot restore) or re-initialize the cluster: back up and delete the db directory and restart with --cluster-init.","If keys hashed with legacy formats exist (empty-string hash or old token format), start once with a version/token that lets migrateTokens collapse them onto the normalized token key."],"exampleFix":"# before: restarted with a changed token\nK3S_TOKEN=NEWTOKEN::server:NEWSECRET k3s server\n# after: restart with the token the cluster was created with\nK3S_TOKEN=K10xxxxxxxx::server:ORIGINALSECRET k3s server","handlingStrategy":"validation","validationCode":"// Before startup (embedding k3s or in a pre-start script): verify the bootstrap key for this token exists and is non-empty.\nfunc bootstrapExists(ctx context.Context, sc store.ReadCloser, token string) (bool, error) {\n\tnorm, err := util.NormalizeToken(token)\n\tif err != nil { return false, err }\n\tkv, err := sc.Get(ctx, storageKey(norm), 0)\n\tif err != nil { return false, err }\n\treturn kv != nil && len(kv.Value) > 0, nil\n}\n// shell: etcdctl get /bootstrap/ --prefix  # expect exactly one non-empty key","typeGuard":null,"tryCatchPattern":"if err := cluster.Bootstrap(...); err != nil {\n\tif strings.Contains(err.Error(), \"no bootstrap data found in datastore\") {\n\t\t// halt; runbook: verify token against first server's token file, then inspect/restore datastore\n\t}\n\treturn err\n}","preventionTips":["Pin the cluster token in a secret store at creation time and never restart with a modified value.","Back up the etcd datastore (or SQL datastore) on a schedule so bootstrap data is always restorable.","Keep the db directory and token file together: wiping one but not the other produces this state."],"tags":["k3s","bootstrap","etcd","token","datastore"],"backgroundTag":null,"analyzedSha":"6ba341e396edc16b8dcae978a7c5e3ac7ee5606e","analyzedAt":"2026-08-15T16:27:54.286Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}