Windows CI failure: restore wallet test case related to pruned blockchain in wallet_assumeutxo.py is failing. #34354

issue maflcko openend this issue on January 20, 2026
  1. maflcko commented at 3:07 pm on January 20, 2026: member

    ISTM that the Windows, ucrt, test cross-built CI failure is unrelated, a restore wallet test case related to pruned blockchain in wallet_assumeutxo.py is failing.

     02026-01-20T13:41:07.2385503Z 2026-01-20T13:41:04.152353Z TestFramework (INFO): Ensuring wallet can't be restored from a backup that was created before the pruneheight (pruned node)
     12026-01-20T13:41:07.2386535Z 
     22026-01-20T13:41:07.2386839Z 2026-01-20T13:41:06.479889Z TestFramework (ERROR): Unexpected exception
     32026-01-20T13:41:07.2387306Z 
     42026-01-20T13:41:07.2387503Z Traceback (most recent call last):
     52026-01-20T13:41:07.2387815Z 
     62026-01-20T13:41:07.2388269Z   File "D:\a\bitcoin\bitcoin\test\functional\test_framework\util.py", line 166, in try_rpc
     72026-01-20T13:41:07.2388901Z 
     82026-01-20T13:41:07.2389049Z     fun(*args, **kwds)
     92026-01-20T13:41:07.2389318Z 
    102026-01-20T13:41:07.2389432Z     ~~~^^^^^^^^^^^^^^^
    112026-01-20T13:41:07.2389660Z 
    122026-01-20T13:41:07.2390180Z   File "D:\a\bitcoin\bitcoin\test\functional\test_framework\coverage.py", line 50, in __call__
    132026-01-20T13:41:07.2390808Z 
    142026-01-20T13:41:07.2391156Z     return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
    152026-01-20T13:41:07.2391651Z 
    162026-01-20T13:41:07.2392093Z   File "D:\a\bitcoin\bitcoin\test\functional\test_framework\authproxy.py", line 156, in __call__
    172026-01-20T13:41:07.2392771Z 
    182026-01-20T13:41:07.2392996Z     raise JSONRPCException(response['error'], status)
    192026-01-20T13:41:07.2393424Z 
    202026-01-20T13:41:07.2395532Z test_framework.authproxy.JSONRPCException: filesystem error: cannot remove: The process cannot access the file because it is being used by another process [D:\a\_temp\test_runner_₿_🏃_20260120_132914\wallet_assumeutxo_56\node3\regtest\w2\wallet.dat] (-1)
    212026-01-20T13:41:07.2397271Z 
    222026-01-20T13:41:07.2397277Z 
    232026-01-20T13:41:07.2397281Z 
    242026-01-20T13:41:07.2397613Z During handling of the above exception, another exception occurred:
    252026-01-20T13:41:07.2398102Z 
    262026-01-20T13:41:07.2398107Z 
    272026-01-20T13:41:07.2398112Z 
    282026-01-20T13:41:07.2398334Z Traceback (most recent call last):
    292026-01-20T13:41:07.2398622Z 
    302026-01-20T13:41:07.2399135Z   File "D:\a\bitcoin\bitcoin\test\functional\test_framework\test_framework.py", line 142, in main
    312026-01-20T13:41:07.2399796Z 
    322026-01-20T13:41:07.2399922Z     self.run_test()
    332026-01-20T13:41:07.2400161Z 
    342026-01-20T13:41:07.2400286Z     ~~~~~~~~~~~~~^^
    352026-01-20T13:41:07.2400474Z 
    362026-01-20T13:41:07.2400948Z   File "D:\a\bitcoin\bitcoin/test/functional/wallet_assumeutxo.py", line 267, in run_test
    372026-01-20T13:41:07.2401587Z 
    382026-01-20T13:41:07.2401827Z     self.test_restore_wallet_pruneheight(n3)
    392026-01-20T13:41:07.2402338Z 
    402026-01-20T13:41:07.2402476Z     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
    412026-01-20T13:41:07.2402806Z 
    422026-01-20T13:41:07.2403384Z   File "D:\a\bitcoin\bitcoin/test/functional/wallet_assumeutxo.py", line 99, in test_restore_wallet_pruneheight
    432026-01-20T13:41:07.2404151Z 
    442026-01-20T13:41:07.2404691Z     assert_raises_rpc_error(-4, error_message, n3.restorewallet, "w2", "backup_w2.dat")
    452026-01-20T13:41:07.2405294Z 
    462026-01-20T13:41:07.2405553Z     ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    472026-01-20T13:41:07.2405970Z 
    482026-01-20T13:41:07.2406496Z   File "D:\a\bitcoin\bitcoin\test\functional\test_framework\util.py", line 157, in assert_raises_rpc_error
    492026-01-20T13:41:07.2407238Z 
    502026-01-20T13:41:07.2407544Z     assert try_rpc(code, message, fun, *args, **kwds), "No exception raised"
    512026-01-20T13:41:07.2408097Z 
    522026-01-20T13:41:07.2408261Z            ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    532026-01-20T13:41:07.2408598Z 
    542026-01-20T13:41:07.2409048Z   File "D:\a\bitcoin\bitcoin\test\functional\test_framework\util.py", line 170, in try_rpc
    552026-01-20T13:41:07.2409645Z 
    562026-01-20T13:41:07.2410041Z     raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
    572026-01-20T13:41:07.2410583Z 
    582026-01-20T13:41:07.2410797Z AssertionError: Unexpected JSONRPC error code -1
    592026-01-20T13:41:07.2411215Z 
    602026-01-20T13:41:07.2411925Z 2026-01-20T13:41:06.484138Z TestFramework (INFO): Not stopping nodes as test failed. The dangling processes will be cleaned up later.
    612026-01-20T13:41:07.2412795Z 
    622026-01-20T13:41:07.2413676Z 2026-01-20T13:41:06.484270Z TestFramework (WARNING): Not cleaning up dir D:\a\_temp\test_runner_₿_🏃_20260120_132914\wallet_assumeutxo_56
    632026-01-20T13:41:07.2414525Z 
    642026-01-20T13:41:07.2415646Z 2026-01-20T13:41:06.484375Z TestFramework (ERROR): Test failed. Test logging available at D:\a\_temp\test_runner_₿_🏃_20260120_132914\wallet_assumeutxo_56/test_framework.log
    652026-01-20T13:41:07.2416737Z 
    66
    672026-01-20T13:42:33.3464929Z wallet_assumeutxo.py                                                             | ✖ Failed  | 8 s
    682026-01-20T13:42:33.3465209Z 
    692026-01-20T13:42:33.3465460Z ALL                                                                              | ✖ Failed  | 2893 s (accumulated) 
    702026-01-20T13:42:33.3465784Z Runtime: 796 s
    

    Originally posted by @rkrux in #33014 (comment)

  2. maflcko added the label Wallet on Jan 20, 2026
  3. maflcko added the label Windows on Jan 20, 2026
  4. maflcko added the label Tests on Jan 20, 2026
  5. maflcko added the label CI failed on Jan 20, 2026
  6. sedited referenced this in commit 5715748333 on Jan 21, 2026
  7. fjahr commented at 8:47 am on January 22, 2026: contributor
    I proposed a fix here: #34377
  8. sedited closed this on Jan 22, 2026

  9. Fabcien referenced this in commit 691dc830c6 on Jan 22, 2026
  10. maflcko commented at 12:43 pm on January 23, 2026: member

    https://github.com/bitcoin/bitcoin/actions/runs/21285353740/job/61266529251?pr=34388#step:12:276:

      0398/451 - wallet_assumeutxo.py failed, Duration: 8 s
      1
      2stdout:
      32026-01-23T12:31:24.007821Z TestFramework (INFO): PRNG seed is: 249974898428252399
      4
      52026-01-23T12:31:24.037053Z TestFramework (INFO): Initializing test directory D:\a\_temp\test_runner__🏃_20260123_122001\wallet_assumeutxo_56
      6
      72026-01-23T12:31:25.327870Z TestFramework (INFO): -- Testing assumeutxo
      8
      92026-01-23T12:31:25.328814Z TestFramework (INFO): Creating a UTXO snapshot at height 299
     10
     112026-01-23T12:31:26.836907Z TestFramework (INFO): Loading snapshot into second node from D:\a\_temp\test_runner__🏃_20260123_122001\wallet_assumeutxo_56\node0\regtest\utxos.dat
     12
     132026-01-23T12:31:26.851777Z TestFramework (INFO): Backup from the snapshot height can be loaded during background sync
     14
     152026-01-23T12:31:26.859014Z TestFramework (INFO): Backup from before the snapshot height can't be loaded during background sync
     16
     172026-01-23T12:31:26.865502Z TestFramework (INFO): Backup from the snapshot height can be loaded during background sync (pruned node)
     18
     192026-01-23T12:31:26.891211Z TestFramework (INFO): Backup from before the snapshot height can't be loaded during background sync (pruned node)
     20
     212026-01-23T12:31:26.897530Z TestFramework (INFO): Test loading descriptors during background sync
     22
     232026-01-23T12:31:26.919150Z TestFramework (INFO): Test that rescanning blocks from before the snapshot fails when blocks are not available from the background sync yet
     24
     252026-01-23T12:31:26.919801Z TestFramework (INFO): Restarting node to stop at height 359
     26
     272026-01-23T12:31:27.580649Z TestFramework (INFO): Restarted node before snapshot validation completed, reloading...
     28
     292026-01-23T12:31:28.106292Z TestFramework (INFO): Ensuring wallet can be restored from a backup that was created before the snapshot height
     30
     312026-01-23T12:31:28.164076Z TestFramework (INFO): Check balance of a wallet that is active during snapshot completion
     32
     332026-01-23T12:31:29.773917Z TestFramework (INFO): Ensuring descriptors can be loaded after background sync
     34
     352026-01-23T12:31:29.817454Z TestFramework (INFO): Ensuring wallet can't be restored from a backup that was created before the pruneheight (pruned node)
     36
     372026-01-23T12:31:31.955307Z TestFramework (ERROR): Unexpected exception
     38
     39Traceback (most recent call last):
     40
     41  File "D:\a\bitcoin\bitcoin\test\functional\test_framework\util.py", line 166, in try_rpc
     42
     43    fun(*args, **kwds)
     44
     45    ~~~^^^^^^^^^^^^^^^
     46
     47  File "D:\a\bitcoin\bitcoin\test\functional\test_framework\coverage.py", line 50, in __call__
     48
     49    return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
     50
     51  File "D:\a\bitcoin\bitcoin\test\functional\test_framework\authproxy.py", line 156, in __call__
     52
     53    raise JSONRPCException(response['error'], status)
     54
     55test_framework.authproxy.JSONRPCException: filesystem error: cannot remove: The process cannot access the file because it is being used by another process [D:\a\_temp\test_runner__🏃_20260123_122001\wallet_assumeutxo_56\node3\regtest\w2_pruneheight\wallet.dat] (-1)
     56
     57
     58
     59During handling of the above exception, another exception occurred:
     60
     61
     62
     63Traceback (most recent call last):
     64
     65  File "D:\a\bitcoin\bitcoin\test\functional\test_framework\test_framework.py", line 142, in main
     66
     67    self.run_test()
     68
     69    ~~~~~~~~~~~~~^^
     70
     71  File "D:\a\bitcoin\bitcoin/test/functional/wallet_assumeutxo.py", line 267, in run_test
     72
     73    self.test_restore_wallet_pruneheight(n3)
     74
     75    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^
     76
     77  File "D:\a\bitcoin\bitcoin/test/functional/wallet_assumeutxo.py", line 99, in test_restore_wallet_pruneheight
     78
     79    assert_raises_rpc_error(-4, error_message, n3.restorewallet, "w2_pruneheight", "backup_w2.dat")
     80
     81    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     82
     83  File "D:\a\bitcoin\bitcoin\test\functional\test_framework\util.py", line 157, in assert_raises_rpc_error
     84
     85    assert try_rpc(code, message, fun, *args, **kwds), "No exception raised"
     86
     87           ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     88
     89  File "D:\a\bitcoin\bitcoin\test\functional\test_framework\util.py", line 170, in try_rpc
     90
     91    raise AssertionError(
     92
     93        "Expected substring not found in error message:\nsubstring: '{}'\nerror message: '{}'.".format(
     94
     95            message, e.error['message']))
     96
     97AssertionError: Expected substring not found in error message:
     98
     99substring: 'Wallet loading failed. Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of a pruned node)'
    100
    101error message: 'filesystem error: cannot remove: The process cannot access the file because it is being used by another process [D:\a\_temp\test_runner_₿_🏃_20260123_122001\wallet_assumeutxo_56\node3\regtest\w2_pruneheight\wallet.dat]'.
    102
    1032026-01-23T12:31:32.009883Z TestFramework (INFO): Not stopping nodes as test failed. The dangling processes will be cleaned up later.
    104
    1052026-01-23T12:31:32.010026Z TestFramework (WARNING): Not cleaning up dir D:\a\_temp\test_runner__🏃_20260123_122001\wallet_assumeutxo_56
    106
    1072026-01-23T12:31:32.010132Z TestFramework (ERROR): Test failed. Test logging available at D:\a\_temp\test_runner__🏃_20260123_122001\wallet_assumeutxo_56/test_framework.log
    108
    1092026-01-23T12:31:32.010359Z TestFramework (ERROR): 
    110
    1112026-01-23T12:31:32.010667Z TestFramework (ERROR): Hint: Call D:\a\bitcoin\bitcoin\test\functional\combine_logs.py 'D:\a\_temp\test_runner_₿_🏃_20260123_122001\wallet_assumeutxo_56' to consolidate all logs
    112
    1132026-01-23T12:31:32.010799Z TestFramework (ERROR): 
    114
    1152026-01-23T12:31:32.010875Z TestFramework (ERROR): If this failure happened unexpectedly or intermittently, please file a bug and provide a link or upload of the combined log.
    116
    1172026-01-23T12:31:32.010978Z TestFramework (ERROR): https://github.com/bitcoin/bitcoin/issues
    118
    1192026-01-23T12:31:32.011060Z TestFramework (ERROR): 
    120
    121
    122
    123stderr:
    124[node 3] Cleaning up leftover process
    125
    126[node 2] Cleaning up leftover process
    127
    128[node 1] Cleaning up leftover process
    129
    130[node 0] Cleaning up leftover process
    131
    132
    133
    134Combine the logs and print the last 99999999 lines ...
    135
    136============
    137Combined log for D:\a\_temp/test_runner__🏃_20260123_122001/wallet_assumeutxo_56:
    138============
    
  11. maflcko reopened this on Jan 23, 2026

  12. fjahr commented at 12:57 pm on January 23, 2026: contributor
    Seems like the problem is rather internal to the restorewallet, probably better if someone with who has a windows enviroment can try to reproduce it, I would need to set it up first…
  13. Sjors commented at 1:41 pm on January 30, 2026: member

    I ran this test a couple of times on a windows machine, but couldn’t reproduce. I’ll let it run in a loop for a while…. Update: still no failure after 400+ runs.

    Maybe there’s some changes I can make to increase the likeliness of failure?

  14. Sjors commented at 3:31 pm on January 30, 2026: member

    The following (vibe coded) patch seems to reliably reproduce the issue on my Windows machine:

     0diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
     1index e72455a3be..c23268d30a 100644
     2--- a/src/wallet/sqlite.cpp
     3+++ b/src/wallet/sqlite.cpp
     4@@ -20,0 +21,5 @@
     5+#ifdef WIN32
     6+#include <windows.h>
     7+#include <thread>
     8+#endif
     9+
    10@@ -376,0 +382,23 @@ void SQLiteDatabase::Close()
    11+
    12+#ifdef WIN32
    13+    // TEST: Immediately after closing SQLite, grab an exclusive lock on the file.
    14+    // This simulates Windows not releasing the file handle immediately after sqlite3_close().
    15+    // The lock is held for 200ms, causing fs::remove() to fail if called too soon.
    16+    std::wstring full_path_w = (m_dir_path / fs::PathFromString(m_file_path)).wstring();
    17+    HANDLE hFile = CreateFileW(
    18+        full_path_w.c_str(),
    19+        GENERIC_READ | GENERIC_WRITE,
    20+        0,  // No sharing - exclusive access
    21+        NULL,
    22+        OPEN_EXISTING,
    23+        FILE_ATTRIBUTE_NORMAL,
    24+        NULL
    25+    );
    26+    if (hFile != INVALID_HANDLE_VALUE) {
    27+        // Detach a thread to hold the lock, so Close() returns immediately
    28+        std::thread([hFile]() {
    29+            std::this_thread::sleep_for(std::chrono::milliseconds(200));
    30+            CloseHandle(hFile);
    31+        }).detach();
    32+    }
    33+#endif
    
  15. Sjors commented at 3:50 pm on January 30, 2026: member

    And here’s a trivial albeit not elegant fix:

     0diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
     1index 64d7f191de..ba3c1d4c75 100644
     2--- a/src/wallet/wallet.cpp
     3+++ b/src/wallet/wallet.cpp
     4@@ -538 +538,7 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& b
     5-        if (wallet_file_copied) fs::remove(wallet_file);
     6+        if (wallet_file_copied) {
     7+            // On Windows, and e.g. on network file systems for all platforms,
     8+            // file handles may not be released immediately after closing, so
     9+            // wait briefly before attempting removal.
    10+            std::this_thread::sleep_for(std::chrono::seconds(1));
    11+            fs::remove(wallet_file);
    12+        }
    

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-02-11 18:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me