util: improve settings.json error message to mention full disk #35384

pull sh011 wants to merge 1 commits into bitcoin:master from sh011:sh011-35373-improve-error-msg changing 3 files +11 −3
  1. sh011 commented at 2:57 PM on May 26, 2026: none

    This PR Fixes #35373. The error message was updated from: "This is probably caused by disk corruption or a crash" to: "This is probably caused by a full disk, disk corruption or a crash"

    The following files were updated:

    1. src/common/settings.cpp -- Updated the main string formatting for the parse failure.
    2. src/test/settings_tests.cpp -- Updated the exact string expectation in the C++ unit test.
    3. test/functional/feature_settings.py -- Updated the expected error message in the Python test suite.

    Configured the Bitcoin Core project natively on Windows using Visual Studio (cmake --preset vs2026-static -DBUILD_GUI=OFF) and it compiled with 100% of the C++ tests passed successfully (347 out of 347).

  2. DrahtBot commented at 2:57 PM on May 26, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35384.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  3. sh011 renamed this:
    Fix for #35373. Updated Error Message
    log: Fix for #35373 -- Updated Error Message
    on May 26, 2026
  4. DrahtBot added the label Utils/log/libs on May 26, 2026
  5. pinheadmz commented at 3:02 PM on May 26, 2026: member

    We have checks in other parts of the code for disk space. Why isn't that being used here to provide specific correct feedback?

  6. sh011 commented at 3:44 PM on May 26, 2026: none

    Hi @pinheadmz , the original change was done as part of the recommendation by the bot for the fix. But based on your comments, I believe it's a better approach so I have updated the PR with new commit to use CheckDiskSpace utility and adjust errors accordingly. Please have a look and let me know if that fixes the issue. Thanks!

  7. pinheadmz commented at 4:21 PM on May 26, 2026: member

    is @sys-dev a bot ?

  8. sh011 commented at 4:36 PM on May 26, 2026: none

    @pinheadmz I wouldn't know but looks like it.

  9. in src/common/settings.cpp:90 in af44551cf0
      86 | @@ -86,9 +87,15 @@ bool ReadSettings(const fs::path& path, std::map<std::string, SettingsValue>& va
      87 |  
      88 |      SettingsValue in;
      89 |      if (!in.read(std::string{std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>()})) {
      90 | -        errors.emplace_back(strprintf("Settings file %s does not contain valid JSON. This is probably caused by disk corruption or a crash, "
      91 | -                                      "and can be fixed by removing the file, which will reset settings to default values.",
      92 | -                                      fs::PathToString(path)));
      93 | +        if (!CheckDiskSpace(path.parent_path())) {
    


    maflcko commented at 7:12 PM on May 26, 2026:

    I don't think this is correct. The corruption will happen when writing the file, not when reading it, which may happen a long time after the out-of-space caused the corruption and the out-of-space may no longer be visible, assuming the init can even get here when the out-of-space is still present?


    sys-dev commented at 3:46 AM on May 27, 2026:

    to be clear, here are the full log entries that occurred:

    bitcoind | Error: Settings file could not be read: bitcoind | - Settings file /home/bitcoin/.bitcoin/settings.json does not contain valid JSON. This is probably caused by disk corruption or a crash, and can be fixed by removing the file, which will reset settings to default values.

    When I inspected the file /home/bitcoin/.bitcoin/settings.json it was there, but was empty (zero length).

    HTH

  10. sys-dev commented at 3:26 AM on May 27, 2026: none

    hello all,

    actually I'm not a bot. lol. just used LLM to generate the issue blurbs.

    the message surfaced during IBD log messages and fooled me into a long troubleshoot of a new hardware build. lots of variables.

    I posted this issue to hopefully result in a simple improvement to the error message to hint that it could be a full disk.

    The real-world failure mode that motivated this issue:

    • Ubuntu Server fresh install with default LVM (allocates only 100G of available space)
    • Bitcoin IBD fills the 100G LV
    • settings.json zero-written, node reports "disk corruption"
    • Actual cause was full disk, not corruption

    thanks so much @sh011 for taking this improvement on, and others here reviewing. If it lands, I think it can save others some time and confusion if disk is full.

  11. maflcko commented at 7:17 AM on May 28, 2026: member
  12. util: improve settings.json error message to mention full disk
    When settings.json contains invalid JSON, mention 'a full disk' as a possible cause alongside disk corruption and crashes. Additionally, check disk space at write time in WriteSettings() to provide a specific error if a write failure is caused by low disk space.
    
    Fixes #35373
    27d51d1bf3
  13. sh011 force-pushed on May 28, 2026
  14. sh011 commented at 3:37 PM on May 28, 2026: none

    Hi @maflcko have squashed my commits into one. Please let me know if anything else is required.

  15. fanquake renamed this:
    log: Fix for #35373 -- Updated Error Message
    util: improve settings.json error message to mention full disk
    on May 28, 2026
  16. sh011 renamed this:
    util: improve settings.json error message to mention full disk
    log: Fix for #35373 -- Updated Error Message util: improve settings.json error message to mention full disk
    on May 28, 2026
  17. winterrdog commented at 9:46 PM on May 28, 2026: none

    Please let me know if anything else is required. @sh011 there's a pending review comment that you might wanna address. it poses an interesting case, check it out

  18. sh011 commented at 4:02 AM on May 29, 2026: none

    Hi @winterrdog I have already addressed the review comment with the fix where now CheckDiskSpace() is being used in the WriteSettings function that will check disk space before writing and throw an error if space is low. Hope that resolves the query.

  19. fanquake renamed this:
    log: Fix for #35373 -- Updated Error Message util: improve settings.json error message to mention full disk
    util: improve settings.json error message to mention full disk
    on May 29, 2026
  20. in src/common/settings.cpp:149 in 27d51d1bf3
     144 | +        errors.emplace_back(strprintf("Error: Unable to write settings file %s", fs::PathToString(path)));
     145 | +        if (!CheckDiskSpace(path.parent_path())) {
     146 | +            errors.emplace_back(strprintf("Error: Disk space is low for %s", fs::PathToString(path.parent_path())));
     147 | +        }
     148 | +        return false;
     149 | +    }
    


    winterrdog commented at 9:50 PM on May 29, 2026:

    i think the watchdog is probably the right place for disk space monitoring. it's proactive, runs continuously (every 5 mins), has a proper threshold, and shuts the node down cleanly before damage spreads. and when disk space gets critically low, the OS itself usually starts signaling that something is wrong too, other processes start failing, logs fill up, the system becomes obviously unhealthy and use-less. because of that, i'm not sure adding CheckDiskSpace inside WriteSettings meaningfully improves discoverability for the user

    from #35373:

    A full disk is a common real-world cause of this exact failure — the file exists but contains zero bytes, producing invalid JSON. The current message does not mention this possibility, leading users to investigate hardware corruption and crashes when the actual cause is simply insufficient disk space.

    it seems like the reporter's actual pain point was not "I didn't realise my disk was full," but rather "I got a confusing error message and started suspecting hardware corruption." the full disk became obvious later; the non-obvious part was the connection between a full disk and an empty settings.json

    so i wonder if the CheckDiskSpace addition may be addressing a problem that already has multiple layers of handling i.e. the watchdog from init.cpp, the OS, and other failing processes, while the real gap here is mostly a UX issue with the error wording itself

    IMO, the one-line message fix already addresses the reporter's actual confusion pretty directly, which makes me think keeping the scope narrow may be the cleaner approach


    sys-dev commented at 2:14 AM on May 30, 2026:

    hello @winterrdog,

    yes, the combo of "corruption" message with no mention of "disk full" and the empty file caused the confusion.

    If the disk is full, with the current WriteSettings logic...

    1. open succeeds and truncates the file
    2. doesn't check for errors on the write or the close
    3. returns true

    This explains the empty file and no record of any errors.

    It would seem good to at least add error checks for both write and close, log any errors, and return false.


    sys-dev commented at 7:09 PM on May 30, 2026:

    The current WriteSettings logic is the root cause. It "corrupts" the settings file by truncating it and silently ditching out when the disk is full.

    If WriteSettings gets fixed so it doesn't clobber the settings file, the other read error message won't appear and its message text could be left as-is.

    This could be done by adding logic to write to a tmp file something like this:

    bool WriteSettings(const fs::path& path,
        const std::map<std::string, SettingsValue>& values,
        std::vector<std::string>& errors)
    {
        SettingsValue out(SettingsValue::VOBJ);
        // Add auto-generated warning comment
        out.pushKV(SETTINGS_WARN_MSG_KEY, strprintf("This file is automatically generated and updated by %s. Please do not edit this file while the node "
                                                    "is running, as any changes might be ignored or overwritten.", CLIENT_NAME));
        // Push settings values
        for (const auto& value : values) {
            out.pushKVEnd(value.first, value.second);
        }
        // Create temporary file in case the settings file is not writable
        fs::path tmp = path;
        tmp += ".tmp";
    
        std::ofstream file;
        file.open(tmp.std_path());
        if (file.fail()) {
            errors.emplace_back(strprintf("Error: Unable to open tmp settings file %s for writing (disk full?)", fs::PathToString(path)));
            return false;
        }
        file << out.write(/* prettyIndent= */ 4, /* indentLevel= */ 1) << std::endl;
        file.close();
        if (file.fail()) {
            errors.emplace_back(strprintf("Error: Unable to write tmp settings file %s (disk full?)", fs::PathToString(path)));
            fs::remove(tmp);
            return false;   
        }                   
        // Rename tmp file to settings file
        std::error_code ec; 
        fs::rename(tmp, path, ec);
        if (ec) {           
            errors.emplace_back(strprintf("Error: Unable to save settings file %s (disk full?)", fs::PathToString(path)));
            fs::remove(tmp);
            return false;   
        }                   
        return true;
    }
    

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-05-31 17:50 UTC

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