{"record":{"id":"a5a5db8ec5d1a298","repo":"hashicorp/nomad","slug":"failed-to-close-boltdb-store-w","errorCode":null,"errorMessage":"failed to close BoltDB store: %w","messagePattern":"failed to close BoltDB store: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/raftutil/migrate.go","lineNumber":141,"sourceCode":"\t// Verify data integrity before finalizing.\n\tsendProgress(progress, \"verifying migrated data\")\n\tif err := verifyMigration(src, dst); err != nil {\n\t\tdst.Close()\n\t\tsrc.Close()\n\t\tcleanupWAL(walDir)\n\t\treturn fmt.Errorf(\"data verification failed: %w\", err)\n\t}\n\n\t// Close both stores before renaming files.\n\tif err := dst.Close(); err != nil {\n\t\tsrc.Close()\n\t\tcleanupWAL(walDir)\n\t\treturn fmt.Errorf(\"failed to close WAL store: %w\", err)\n\t}\n\n\tif err := src.Close(); err != nil {\n\t\tcleanupWAL(walDir)\n\t\treturn fmt.Errorf(\"failed to close BoltDB store: %w\", err)\n\t}\n\n\t// Rename the old BoltDB file to preserve it as a backup with timestamp.\n\ttimestamp := time.Now().Format(\"20060102-150405\")\n\tbackupPath := fmt.Sprintf(\"%s.migrated.%s\", boltPath, timestamp)\n\tif err := os.Rename(boltPath, backupPath); err != nil {\n\t\treturn fmt.Errorf(\"migration succeeded but failed to rename %s to %s: %w\",\n\t\t\tboltPath, backupPath, err)\n\t}\n\n\tsendProgress(progress, fmt.Sprintf(\"migration complete; old BoltDB file preserved at %s\", backupPath))\n\treturn nil\n}\n\nfunc sendProgress(progress chan<- string, msg string) {\n\tif progress != nil {\n\t\tselect {\n\t\tcase progress <- msg:","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/raftutil/migrate.go#L123-L159","documentation":"After the WAL store closes successfully, the source BoltDB store must also be closed before its file is renamed to a backup. This error wraps a failure closing the BoltDB handle — typically an fsync/flush failure on raft.db. The WAL directory is removed and the BoltDB file is left in place, so the migration can be retried, but it indicates possible trouble with the source storage.","triggerScenarios":"src.Close() returns an error: bbolt fails to flush pages or fsync the raft.db file on close (ENOSPC, EIO), or the file descriptor is in a bad state.","commonSituations":"Disk full at close time; failing disk or network storage returning I/O errors; raft.db previously damaged by a crash; extremely loaded host preventing flush completion.","solutions":["Read the wrapped error and fix the storage issue (free space, replace failing disk).","Run bolt check on raft.db to confirm the source store is still intact before retrying.","Re-run MigrateToWAL once storage health is restored; the failed WAL directory has been removed.","Take a filesystem-level copy of raft.db before further attempts if I/O errors persist."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify source health before migrating:\ncmd := exec.Command(\"bolt\", \"check\", filepath.Join(raftDir, \"raft.db\"))\nif err := cmd.Run(); err != nil {\n    return fmt.Errorf(\"raft.db failed integrity check: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := raftutil.MigrateToWAL(ctx, raftDir, progress)\nif err != nil && strings.Contains(err.Error(), \"failed to close BoltDB store\") {\n    // raft.db left in place; check storage, run bolt check, then retry\n}","preventionTips":["Check disk health (smartctl/dmesg) before migrating on suspect hardware.","Keep free disk space for bbolt to flush and fsync on close.","Back up raft.db at the filesystem level before migrating.","Run bolt check on any raft.db from a crashed node before migration."],"tags":["boltdb","close-failed","fsync","io"],"backgroundTag":"bolt-close-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}