ElementsProject / ElementsProject/lightning

setconfig aborts lightningd (FATAL SIGNAL 6) when it cannot persist the change: "Could not write to config : No such file or directory"

Open
#9,351 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
3.1k
Forks
1k
Avg merge
4d 10h
Merged PRs (30d)
13

Description

## Issue and Steps to Reproduce

Calling `setconfig` on a node whose configuration file is not writable by the daemon crashes the entire node with `FATAL SIGNAL 6` (abort), instead of returning a JSON-RPC error. The crash happens in the persistence step (`setconfig_success → configvar_save → create_setconfig_include → append_to_file`), i.e. after the command has been accepted.

Setup (a fairly standard hardened systemd deployment):

- lightningd v26.06.6 started as `lightningd --conf=/etc/lightning/lightning.conf`
- `/etc/lightning/lightning.conf` is owned by root; the service runs as `User=lightning` with systemd hardening, so `/etc` is read-only to the daemon:
```ini
[Service]
ExecStart=/usr/local/bin/lightningd --conf=/etc/lightning/lightning.conf
User=lightning
PrivateTmp=true
ProtectSystem=full
ProtectHome=read-only
NoNewPrivileges=true
PrivateDevices=true
```
- Relevant config contents (sanitized):
```
network=bitcoin
lightning-dir=/var/lib/lightning # writable by the daemon
rpc-file=/var/lib/lightning-rpc/lightning-rpc
rpc-file-mode=0660
```
- The option being set (`min-capacity-sat`) was not previously set in any config file.

Steps:

1. `lightning-cli setconfig min-capacity-sat 2000000`
→ returns success to the client, but `listconfigs min-capacity-sat` still shows `10000` / `"source": "default"`, and nothing is persisted. (Silent no-op reported as success — arguably a second bug.)
2. Run the identical `setconfig` again
→ `lightning-cli` gets `reading response: socket closed`; lightningd logs `**BROKEN** lightningd: Could not write to config : No such file or directory` and aborts.

Note the error message contains an **empty filename** (`to config :`), which may point at the underlying cause — the include-file path apparently resolves to an empty string in this layout.

## Expected behavior

- If persistence fails, `setconfig` should return a JSON-RPC error (and ideally roll back or keep the value as runtime-only with a warning) — a failed `open()`/`write()` in an RPC handler should never `fatal()` the daemon.
- A `setconfig` call that changes and persists nothing should not report success.

## Actual behavior

The node aborts mid-operation (ours was mid block-scan; systemd's `Restart=on-failure` brought it back, but on an unsupervised node this is an outage; on a node with active channels it is a crash during live operation, triggerable by any operator using a documented RPC).

## Crash log / backtrace

```
Could not write to config : No such file or directory
2026-07-24T14:42:03.795Z **BROKEN** lightningd: Could not write to config : No such file or directory
lightningd: FATAL SIGNAL 6 (version v26.06.6)
0x600bab42c365 send_backtrace
common/daemon.c:38
0x600bab42c401 crashdump
common/daemon.c:83
0x783308695b2c ???
pthread_kill+0x11c:0
0x78330863c27d ???
gsignal+0x1d:0
0x78330861f8fe ???
abort+0xde:0
0x600bab3bc300 fatal_vfmt
lightningd/log.c:1128
0x600bab3bc39f fatal
lightningd/log.c:1138
0x600bab3ef823 append_to_file
lightningd/configs.c:351
0x600bab3ef99b create_setconfig_include
lightningd/configs.c:496
0x600bab3efc24 configvar_save
lightningd/configs.c:513
0x600bab3f02d8 setconfig_success
lightningd/configs.c:600
0x600bab3f086d json_setconfig
lightningd/configs.c:804
0x600bab3b3c13 command_exec
lightningd/jsonrpc.c:771
0x600bab3b59b1 rpc_command_hook_final
lightningd/jsonrpc.c:912
0x600bab3e6a7d hook_done
lightningd/plugin_hook.c:243
0x600bab3e6bae plugin_hook_call_next
lightningd/plugin_hook.c:343
0x600bab3e78c3 plugin_hook_call_
lightningd/plugin_hook.c:395
0x600bab3b607d plugin_hook_call_rpc_command
```

A full `crash.log` from the incident is available on request.

## Environment

- Core Lightning v26.06.6 (built from source)
- Debian-based Linux inside a Proxmox LXC container, systemd-managed service
- bitcoind backend on the same host (was still catching up on blocks at the time; likely irrelevant)

## Workaround

Avoid `setconfig` on deployments where the daemon cannot write its own config; edit the config file and restart instead. (Arguably a config file that the daemon cannot rewrite is a deliberate hardening choice, which is why graceful degradation would be valuable here.)

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in lightningd/configs.c, tracing json_setconfig through setconfig_success, configvar_save, create_setconfig_include, and append_to_file. Reproduce the unwritable-config case and inspect existing setconfig or configuration persistence tests. Done means persistence failures return a JSON-RPC error without aborting lightningd, and a change that is not persisted is not reported as successful.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.