Configuration Flag Reference
This chapter is the complete reference for every config key satd recognizes:
what it does, its default, whether it reloads live on SIGHUP, and whether it
is Bitcoin Core-compatible or a satd extension.
For how configuration is sourced and how live reload works, see
Configuration, Tuning & Reload. This chapter is the flat
per-key index. The auth keys (authfile, *authbearer/*auth,
*allowremote, cookie/rpcuser/rpcauth) are explained in context in
Authentication & Authorization. The sync, consensus, and
storage-tuning keys (assumevalid, consensus, shadow*, dbcache,
prefetchworkers, maxahead, storageprofile, the rocksdb* / compaction*
family, reindex) are covered in Initial Block Download & Fast Sync.
How satd reads configuration
The goal is that an existing Bitcoin Core bitcoin.conf drops in and works.
satd reads Core's configuration surface directly: the same
bitcoin.conf / satd.conf key=value and [network] section syntax, and
the same flag names (-datadir, -rpcport, …). Supported names and semantics
track Bitcoin Core v30.
- Resolution order.
-conf=<path>if given, else<datadir>/bitcoin.conf, else<datadir>/satd.conf. Flags override file values. - Key disposition. Each config-file key gets one of four treatments:
- Honored. satd implements it. This is the common case.
- Skipped with a warning. A recognized Core v30 option satd does not
implement but that is safe to skip. The node still starts, and a
WARNline names the ignored key and the satd equivalent, if any. This is what lets a realbitcoin.confboot unedited. - Rejected at load. A small set where skipping would mislead you about the node's security, exposure, or privacy posture (see Unsupported Core keys). satd fails closed with guidance.
- Rejected as a typo. A key that is neither a satd option nor a known
Core v30 option. Rejection stops a mistyped security option such as
rpcusser=from silently disabling auth.
- No key is silently ignored. Skipped keys always warn; nothing a config asks for is dropped without a log line.
-profile=<preset>seeds a hardware/role profile (archival,pruned-home,mining,regtest-dev,signet-watchtower). Explicit flags override the profile's values.
Note. Compatibility is pinned to Bitcoin Core v30, a frozen and verifiable surface. Keys Core adds in v31 or later (for example
limitclustercount,limitclustersize,privatebroadcast,txospenderindex) are not recognized and are rejected as typos until the pin is bumped. Keys Core removed at or before v30 (for exampleupnp,maxorphantx) are likewise not honored. Abitcoin.confmigrated from a newer Core that contains a v31+ key stops satd at startup with an "unknown key" error. This is intentional.
Note. This reference is for operating the node. To write software that consumes node state (blocks, mempool, address activity, reorgs), use the Streaming Consumption API (gRPC, WebSocket, or ZMQ). It is reorg-safe, supports durable cursor replay, and is decoupled from consensus. The Core
*notifyshell hooks and RPC polling exist for compatibility and quick scripts only. They have no delivery guarantee, no replay, and no reorg awareness.
Legend
- Reload.
hot: applied live onSIGHUP(systemctl reload satd).restart: wired into long-lived state at startup; reported as "restart required" on reload, never silently ignored. TLS certificate contents reload viaSIGUSR1even where the key isrestart; see Live TLS Certificate Reload. - Compat.
core: same key name and substantially the same semantics as Bitcoin Core.satd: a satd-specific extension (no Core equivalent, or satd-only semantics). The classification is best-effort; a key modeled on Core behavior but without a Core flag of the same name issatd.
Note. Every key in the per-category tables below is honored: satd implements it. Recognized Core v30 keys satd does not honor are not in these tables. They are listed, with their warn-and-skip or fail-closed disposition, under Unsupported Core keys: skipped vs rejected. A key in neither place is rejected as a typo.
Network selection
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
regtest | off | restart | core | Use the regtest network. |
testnet | off | restart | core | Use the testnet network. |
testnet4 | off | restart | core | Use the testnet4 network. |
signet | off | restart | core | Use the signet network. |
chain | main | restart | core | Unified network selector: main|test|signet|regtest|testnet4. Alternative to the per-net flags. |
The bare selectors (signet=1, testnet4=1, …) and chain= are honored both
on the command line and in bitcoin.conf, as in Bitcoin Core. Command-line
selectors take precedence over the config file. Selecting more than one network
(two bare selectors, or a chain= that disagrees with a bare selector) is a
startup error.
Filesystem
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
datadir | platform default | restart | core | Data directory. |
blocksdir | <datadir>/blocks | restart | core | Alternative location for blocks/ and flat-file undo data. |
blocksxor | unset | restart | core | Blocks-dir *.dat XOR obfuscation (Core v28+ blocks/xor.dat). Unset: honor an existing key (an obfuscated Core v28+ blocks/ dir reads with no config) and initialize fresh dirs plaintext. 1: also generate a random key on a brand-new blocks dir (Core's default). 0: demand plaintext; refuses a dir with a nonzero stored key. |
conf | bitcoin.conf in datadir | restart | core | Config file path. |
includeconf | none | restart | core | Additional config file to splice in; honored only inside a config file. |
pid | none | restart | core | Write PID to file. |
profile | none | restart | satd | Named preset: archival|pruned-home|mining|regtest-dev|signet-watchtower; CLI flags override it. |
Daemon control
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
daemon | off | restart | core | Run in background; accepted for compatibility (no-op; use systemd). |
server | on | restart | core | Accept RPC commands; accepted for compatibility (always on). |
logformat | text | restart | satd | Log output format: text or json. Only verbosity hot-reloads, not the format. |
logtimestamps | on | restart | core | Prepend a timestamp to each log line. Disable (-nologtimestamps) when journald / the container runtime already stamps lines. |
logthreadnames | off | restart | core | Prepend the originating thread name to each log line. |
logsourcelocations | off | restart | core | Prepend source file:line to each log line. |
debug | none | hot | core | Enable debug logging for a category (repeatable; bare/all/1 = everything). satd adds stratum, the Stratum server's per-miner lines (see Verifying a miner). |
debugexclude | none | hot | core | Disable debug logging for a category debug would otherwise enable. |
loglevel | info | hot | core | Global verbosity (trace/debug/info/warn/error) or a per-category override (net:debug). Maps onto satd's tracing filter: a bare level sets the default for targets without an override, and does not lower a more specific -debug/RUST_LOG directive (-debug=net -loglevel=error still logs net at debug). A category:level pair overrides that subsystem. |
allowignoredconf | off | restart | core | Suppress startup warnings about includeconf files satd had to ignore. |
maxshutdownsecs | 30 | hot | satd | Max graceful-shutdown flush duration (seconds) before force exit. |
RPC server
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
rpcport | 8332 (network-dependent) | restart | core | RPC server port. Defaults: main 8332, test 18332, testnet4 48332, signet 38332, regtest 18443. |
rpcbind | 127.0.0.1:<rpcport> and [::1]:<rpcport> | restart | core | Bind plain-HTTP JSON-RPC to address (repeatable). Non-loopback requires rpcallowip. With no rpcbind, a default that cannot be bound (no IPv6) is skipped. |
rpcallowip | loopback only | restart | core | Per-request source-IP allowlist for JSON-RPC (repeatable). IPv6 may be bracketed ([::1]). |
cjdnsreachable | false | restart | core | satd has no CJDNS transport; as in Core, an rpcallowip in fc00::/8 is refused while it is set. |
rpcuser | none | hot | core | RPC username. |
rpcpassword | none | hot | core | RPC password. |
rpcthreads | 16 | restart | core | Max concurrent in-flight RPC method calls. |
rpcworkqueue | 64 | restart | core | Max queued RPC requests beyond rpcthreads before HTTP 429 (Core returns 503; documented divergence). |
rpcservertimeout | 30 | restart | core | Seconds a client may take to deliver a complete request (head and body), or sit idle between keep-alive requests, before the connection is closed. 0 disables. |
apithreads | max(2, cores/4) | restart | satd | Worker threads for the isolated API runtime (Esplora/Electrum/events gRPC/metrics). |
rpcreadonlybind | none | restart | satd | Bind an opt-in read-only JSON-RPC listener (reads + mempool submit) on the API runtime. |
rpcreadonlyport | 8330 | restart | satd | Default port for rpcreadonlybind entries without an explicit port. |
rpcreadonlyallowip | loopback only | restart | satd | Source-IP allowlist for the read-only listener. |
rpcreadonlythreads | = rpcthreads | restart | satd | Max in-flight calls on the read-only listener. |
rpcreadonlyworkqueue | = rpcworkqueue | restart | satd | Read-only listener work-queue depth before HTTP 429. |
rpcreadonlytlsbind | none | restart | satd | TLS bind for the read-only listener (requires cert+key). |
rpcreadonlytlscert | none | restart | satd | PEM certificate (chain) for the read-only TLS listener. |
rpcreadonlytlskey | none | restart | satd | PEM private key for the read-only TLS listener. |
rpcreadonlymtls | false | restart | satd | Require a client cert (mTLS) on the read-only TLS surface. |
rpcreadonlymtlsclientca | none | restart | satd | CA bundle client certs must chain to on the read-only TLS surface. |
rpcreadonlymtlsclientallow | any CA-signed | restart | satd | Allowlist of client-cert subjects on the read-only TLS surface. |
rpcauth | none | hot | core | HMAC-SHA256 RPC credential user:salt$hash (Core rpcauth format; repeatable). An empty or malformed entry stops startup; -norpcauth discards the entries before it and the config file's. |
authfile | none | restart | satd | Path to unified-auth bearer-token file (TOML); enables the opt-in bearer-auth layer. Token contents reload live. |
rpcauthbearer | false | restart | satd | Honor Authorization: Bearer tokens on the JSON-RPC listeners (requires authfile). |
rpccookiefile | $DATADIR/.cookie | restart | core | Override the auto-generated cookie file path. -norpccookiefile writes no cookie. |
rpccookieperms | owner (0600) | restart | core | Cookie file permissions: owner(0600)|group(0640)|all(0644). |
rpcdefaultunits | btc | hot | satd | Default units for RPC amount fields: btc (Core-compatible) or sats. |
rpcdisableauth | false | restart | satd | Disable HTTP Basic auth on the JSON-RPC TLS surface; only valid with rpcmtls=1. |
rpcextendederrors | off | hot | satd | Emit structured error payloads (category/suggestion/debug) on RPC errors. |
RPC TLS
(satd-specific; Core's RPC is HTTP-only behind a TLS-terminating sidecar.)
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
rpctlsbind | none | restart | satd | Bind the JSON-RPC TLS listener (requires cert+key). |
rpctlscert | none | restart | satd | PEM TLS certificate for the JSON-RPC server. |
rpctlskey | none | restart | satd | PEM TLS private key for the JSON-RPC server. |
rpctlshandshaketimeout | 10 | restart | satd | Per-handshake timeout (seconds) for the JSON-RPC TLS surface. |
rpcmtls | false | restart | satd | Require mutual TLS on the JSON-RPC TLS listener. |
rpcmtlsclientca | none | restart | satd | PEM CA bundle to verify client certs when rpcmtls=1. |
rpcmtlsclientallow | any CA-signed | restart | satd | Allowlist of accepted client-cert CN/DNS-SAN values. |
P2P
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
listen | on (see note) | restart | core | Accept P2P connections. The default is soft, as in Core: a node given any connect (including connect=0 / -noconnect), or maxconnections ≤ 0, does not accept inbound either, since a node pinned to specific peers has not asked to be reachable. bind or whitebind raises it back, and an explicit listen — flag or config file — beats both. Because the value is derived, changing a hot key that feeds it (connect, maxconnections) over SIGHUP logs a listen restart-required notice; the running listener is not started or stopped until a restart. A listen that is off in turn soft-sets listenonion off, as in Core, so a pinned node does not publish a hidden service; an explicit listenonion beats that. satd does not implement Core's third soft-set, where a proxy also lowers listen — a Tor-proxied satd is still reachable on clearnet unless you set listen=0. |
networkactive | on | hot | core | Start with P2P networking enabled. =0 boots with networking paused (no inbound accepts, no outbound dials); change it at runtime with the setnetworkactive RPC. |
blocksonly | false | hot | core | Suppress P2P transaction relay; locally-submitted txs still relayed. |
v2transport | true | hot | core | Offer/accept BIP 324 v2 encrypted transport (Core default since v26). |
v2only | false | hot | satd | Refuse peers that do not speak BIP 324 v2 (privacy hardening). |
externalip | none | hot | core | External address to advertise to peers (repeatable). |
whitelist | none | hot | core | Grant net permissions to peers by source subnet (repeatable). [<perms>@]<subnet>. Inbound only unless the permission list carries out, as in Core; an out entry applies only to manual outbound connections (connect / addnode), never to automatic ones. @<subnet> with an empty list matches the range and grants nothing. A peer arriving over the Tor hidden service is never matched against this — it reaches the node on a loopback socket Tor forwards to, so matching would grant an anonymous remote peer whatever you granted your own machine. |
whitelistrelay | on | hot | core | Grant relay to whitelisted peers with default permissions (relay their txes even under -blocksonly). Entries with an explicit perms@ prefix are unaffected. |
whitelistforcerelay | off | hot | core | Grant forcerelay to whitelisted peers with default permissions. Entries with an explicit perms@ prefix are unaffected. |
whitebind | none | restart | core | Bind an extra permissioned P2P listener (repeatable). |
asmap | none | restart | core | asmap file for ASN-based addrman bucketing (eclipse resistance). |
port | network default | restart | core | P2P listen port. |
bind | 0.0.0.0 | restart | core | Bind P2P to this address; repeatable. Accepts addr, addr:port, and addr[:port]=onion. An entry with a port uses it; a bare address takes port, and a bare =onion entry takes port + 1 (as in Core). IPv6 literals may be plain (::1) or bracketed. Any explicit bind replaces the default listener. Cannot be combined with listen=0. |
connect | none | hot | core | Connect only to specific peer(s) (repeatable). An entry with no port takes the network's default P2P port. Any connect stops the node dialling addresses it learns from gossip and soft-sets listen=0 (see listen); connect=0 — and the command-line negation -noconnect — is Core's spelling for "open no outbound connections at all"; a literal connect=0 mixed with a peer address is refused, since Core keeps the peer and satd will not dial the 0. Connect-only exclusivity is a startup decision (restart to change). |
addnode | none | hot | core | Add a node to connect to (does not disable DNS seeding, and does not affect listen). An entry with no port takes the network's default P2P port. |
uacomment | none | restart | core | Append a comment to the advertised user agent (repeatable; command-line and config-file values accumulate, command line first). Renders as /satd:<version>(c1; c2)/. A comment may contain only alphanumerics and .,;-_?@ — the user agent's own delimiters /, :, ( and ) are refused — and the whole user agent may not exceed 256 bytes. Either violation is a startup error, as in Core. |
seednode | none | hot | core | One-shot seed peer connected at startup to bootstrap discovery. |
maxconnections | 125 | hot | core | Maximum total connections. 0 (or any value ≤ 0) soft-sets listen=0, as in Core — see listen. That half is a startup decision: changing maxconnections over SIGHUP applies the new cap but does not start or stop the listener. |
maxinboundperip | 3 | hot | satd | Max simultaneous inbound peers from one source IP (Core-style flood guard; no Core flag). |
cmpctblockprefill | false | restart | satd | Announce a new block as a cmpctblock with the transactions this node lacked when it arrived prefilled, so a peer that lacks them too rebuilds the block without a getblocktxn round trip. Bitcoin Core's proposed design (#35558, not yet merged in Core); off until measurement says otherwise. |
cmpctblockprefillbytes | 8192 | restart | satd | Transaction bytes a cmpctblockprefill announcement may carry beyond the coinbase. Transactions nobody relayed to this node go first, then replaced or policy-refused ones; one that does not fit is skipped. 0 prefills nothing. |
blockreconstructionextratxn | 100 | restart | core | Recently seen transactions that are not in the mempool — replaced, or refused by policy — kept so a compact block that includes one still reconstructs without a round trip. 0 keeps none. |
maxuploadtarget | 0 (unlimited) | hot | core | Soft cap (bytes/24h) on historical block upload. |
dns | true | restart | core | Allow DNS lookups for -addnode/-seednode/-connect. With dns=0 those options accept only literal IP addresses and .onion targets; a hostname is refused. |
dnsseed | true | restart | core | Query DNS seeds for peer addresses (requires dns). |
forcednsseed | false | restart | core | Always query DNS seeds even with a populated address book. |
fixedseeds | true | restart | core | Allow the compiled-in fixed-seed fallback. |
bantime | 86400 | hot | core | Ban duration in seconds. |
timeout | 5000 ms | hot | core | P2P connection timeout in milliseconds (accepts 5s/5000ms). |
onlynet | all | restart | core | Restrict to network types: ipv4, ipv6, onion. |
signetseednode | built-in seeds | restart | core | Additional signet seed node (repeatable; signet only). |
signetchallenge | default signet | restart | core | Custom signet challenge script, hex (BIP 325; signet only). |
Note. satd answers a peer's BIP35
mempoolmessage (a request to announce our entire mempool) only for peers granted themempoolnet permission:-whitelist=mempool@<subnet>,all@<subnet>, or a bare-whitelist=<subnet>entry, whose implicit permission set includesmempool, as in Core. The permission is not implied bynoban@. The response honors the requesting peer's fee filter, and dumps to one peer are rate-limited to at most one per 30 s. satd does not advertiseNODE_BLOOM(BIP37 bloom filters are unsupported).mempoolrequests from peers without the permission are ignored, which is softer than Bitcoin Core with bloom disabled: Core disconnects such peers unless they havenoban.
Proxy / Tor
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
proxy | none | restart | core | SOCKS5 proxy for all outbound connections. A hostname in -addnode/-seednode/-connect is refused while this is set, rather than resolved by the local resolver — that lookup would leak the peer names the proxy is there to hide. Use a literal IP or a .onion address. |
proxyrandomize | on | restart | core | Use fresh random SOCKS5 credentials per connection so Tor isolates each peer on its own circuit (IsolateSOCKSAuth). Relies on Tor's default SocksPort isolation; a no-op on a non-Tor SOCKS proxy (or one with IsolateSOCKSAuth disabled), where credentials are not negotiated. Set =0 to opt out. |
onion | = -proxy | restart | core | SOCKS5 proxy for .onion connections. |
torcontrol | 127.0.0.1:9051 | restart | core | Tor control port for the hidden service. Auth is negotiated via PROTOCOLINFO: SAFECOOKIE (stock-Tor default) when no password is set, else password, else null. |
torpassword | none | restart | core | Tor control port password (for a HashedControlPassword setup). Leave unset to use SAFECOOKIE cookie auth. |
listenonion | off (on if torcontrol set) | restart | core | Create a Tor v3 hidden service via the control port. Soft-set off when listen is off, as in Core; state it explicitly to keep the service on a non-listening node. Gets its own P2P listener on 127.0.0.1:<port+1> unless a bind=<addr>:<port>=onion entry names one, matching Core's onion_binds; peers arriving there are exempt from whitelist matching. |
Consensus
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
assumevalid | per-network hash | restart | core | Skip script verification up to HASH (0=verify all, all=skip old blocks). |
assumevalidage | 86400 | restart | satd | With assumevalid=all, still verify scripts for blocks newer than SECS. |
checkpoints | on | restart | core | Enforce the built-in block checkpoints. -checkpoints=0 disables checkpoint validation. |
stopatheight | none | restart | core | Stop once the active-chain tip reaches HEIGHT. |
testactivationheight | none | restart | core | Regtest only (warned and ignored elsewhere): name@height buried-deployment override (bip34|dersig|cltv|csv|segwit), repeatable. Note Core's own asymmetry, which satd matches: this option takes dersig/cltv, while getdeploymentinfo reports the same deployments as bip66/bip65; command-line and config-file occurrences merge, last wins per name. |
vbparams | none | restart | core | Regtest only (warned and ignored elsewhere): deployment:start:end[:min_activation_height] BIP 9 window override. Only testdummy is accepted — satd activates taproot at a fixed height and counts no signalling, so an override for it would be reported and not honoured, and is refused by name. |
consensus | rust-shadow | restart | satd | Consensus engine: cpp|rust|rust-shadow|cpp-shadow. |
Indexing
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
txindex | off | restart | core | Maintain a full transaction index. |
addressindex | on | restart | satd | Maintain an address-history index (backs native Electrum/Esplora). |
addrindexsubscriptions | 10000 | hot | satd | Max concurrent per-scripthash status subscriptions. |
blockfilterindex | off | restart | core | BIP 158 compact-block-filter index (basic/0/1, or no value for basic). |
peerblockfilters | off | hot | core | Advertise NODE_COMPACT_FILTERS and serve BIP 157 filters; implies blockfilterindex=basic. |
silentpaymentindex | off | restart | satd | BIP 352 silent-payment tweak index (sp_tweaks); backs the streaming tweaks firehose and scan-key-watch rescan. Backfill an existing datadir with backfillindex silentpayment. |
coinstatsindex | off | restart | core | Accepted so a Core bitcoin.conf drops in unchanged. satd implements no UTXO-set hash index: the key sets nothing, and getindexinfo reports the index as never synced rather than claiming a readiness it cannot deliver. |
txospenderindex | off | restart | core | Accepted so a Core bitcoin.conf drops in unchanged. satd has no separate spender index; getindexinfo answers from the outpoint_spend index that actually backs gettxspendingprevout. |
Mempool / relay policy
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
mempoolfullrbf | on | hot | satd | Enable full replace-by-fee. Core removed this flag in v28 (full-RBF is now unconditional there); satd retains the flag. |
maxmempool | 300 MB | hot | core | Maximum mempool size in MB. |
minrelaytxfee | 1000 sat/kvB | hot | core | Minimum relay fee rate. A bare integer is sat/kvB; a decimal is BTC/kvB, Bitcoin Core's spelling (0.00001 = 1000 sat/kvB). |
dustrelayfee | 3000 sat/kvB | hot | core | Dust relay fee rate. A bare integer is sat/kvB; a decimal is BTC/kvB, Bitcoin Core's spelling (0.00003 = 3000 sat/kvB). |
datacarrier | on | hot | core | Accept OP_RETURN outputs. |
datacarriersize | 83 bytes | hot | core | Maximum OP_RETURN size in bytes (0 = reject all). |
limitclustercount | 64 | hot | core | Do not accept a transaction directly or indirectly connected to this many or more other unconfirmed transactions. 64 is both the default and the maximum, so the option can only lower it; a larger value is a startup error. Exceeding the limit is rejected as too-large-cluster. |
limitancestorcount | 25 | hot | core | Maximum unconfirmed ancestor count. Deprecated in Bitcoin Core v31 and superseded by limitclustercount; accepted for config compatibility but no longer gates admission. |
limitdescendantcount | 25 | hot | core | Maximum unconfirmed descendant count. Deprecated alongside limitancestorcount, and likewise no longer gates admission. |
mempoolexpiry | 336 h | hot | core | Mempool entry expiry in hours. |
maxtipage | 86400 s | restart | core | A tip older than this keeps the node in initial block download. |
persistmempool | on | hot | core | Persist the mempool to mempool.dat across restarts. |
rebroadcastinterval | 0 (auto) | hot | satd | Seconds between rebroadcasts of unconfirmed local transactions (those submitted here via sendrawtransaction, the MCP tool, Esplora POST /tx, or Electrum transaction.broadcast). 0 = auto: a randomized 10–15 min interval per pass, matching Bitcoin Core. A locally-submitted tx is re-announced until enough peers take it (see broadcastconfirmpeers) or it leaves the mempool, so it still propagates if no peer was connected at submit time; the pending set is persisted in mempool.dat so it also survives restarts. A SIGHUP interval change applies after the in-flight sleep completes. |
broadcastconfirmpeers | 1 | hot | satd | Distinct peer IPs that must take a locally-broadcast tx before it counts as propagated and rebroadcast stops. A peer takes a tx by fetching it via getdata (the primary signal) or announcing it back via inv. Counted per IP, not per connection, so a reconnecting host is one witness. Raising it demands wider observed propagation before retries stop. |
permitbaremultisig | on | hot | core | Allow bare multisig outputs. |
acceptnonstdtxn | off | hot | core | Relay and accept non-standard transactions (bypass the standardness relay checks: oversize, dust, OP_RETURN/datacarrier, non-standard scripts). Consensus rules are never relaxed. Intended for test/dev networks. |
Esplora
(satd-specific; native Esplora REST server. See Esplora REST API.)
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
esplora | on | restart | satd | Run the native Esplora REST server (requires addressindex=1). |
esplorabind | 127.0.0.1:3000 | restart | satd | Bind the Esplora REST listener. |
esploratlsbind | none | restart | satd | Bind the Esplora TLS listener (requires cert+key). |
esploratlscert | none | restart | satd | PEM TLS certificate for the Esplora server. |
esploratlskey | none | restart | satd | PEM TLS private key for the Esplora server. |
esploramtls | false | restart | satd | Require mutual TLS on the Esplora TLS listener. |
esploramtlsclientca | none | restart | satd | PEM CA bundle to verify client certs when esploramtls=1. |
esploramtlsclientallow | any CA-signed | restart | satd | Allowlist of accepted client-cert CN/DNS-SAN values. |
esploraprefix | / | restart | satd | URL prefix to mount the API under (/api for blockstream-style). |
esploracors | none | restart | satd | Allowed CORS origin (repeatable). |
esplorarequesttimeout | 30 | restart | satd | Per-request handler timeout (seconds). |
esploramaxconns | 256 | restart | satd | Hard cap on concurrent in-flight Esplora requests. |
esplorasseconns | = esploramaxconns | restart | satd | Hard cap on simultaneously-open SSE streams (0 disables SSE). |
esploraauth | none | restart | satd | Esplora auth mode: none|cookie|userpass. |
esploraauthbearer | false | restart | satd | Honor bearer tokens (esplora:read) on the Esplora server (requires authfile). |
esploracookiefile | shared .cookie | restart | satd | Cookie file when esploraauth=cookie. |
esplorauserpass | none | restart | satd | Static user:pass when esploraauth=userpass. |
Electrum
(satd-specific; native Electrum protocol server.)
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
electrum | off | restart | satd | Run the native Electrum protocol server (requires addressindex=1 and txindex=1). |
electrumbind | 127.0.0.1:50001 | restart | satd | Bind the Electrum plain-TCP listener. |
electrumtlsbind | none (std port 50002) | restart | satd | Bind the Electrum TLS listener (requires cert+key). |
electrumtlscert | none | restart | satd | PEM TLS certificate for the Electrum server. |
electrumtlskey | none | restart | satd | PEM TLS private key for the Electrum server. |
electrummtls | false | restart | satd | Require mutual TLS on the Electrum TLS listener. |
electrummtlsclientca | none | restart | satd | PEM CA bundle to verify client certs when electrummtls=1. |
electrummtlsclientallow | any CA-signed | restart | satd | Allowlist of accepted client-cert CN/DNS-SAN values. |
electrummaxconns | 64 | restart | satd | Hard cap on simultaneously-open Electrum connections. |
electrummaxsubsperconn | 1000 | restart | satd | Per-connection scripthash subscription cap. |
electrumrequesttimeout | 30 | restart | satd | Per-request handler timeout (seconds). |
electrummaxbatchrequests | 100 | restart | satd | Max requests per JSON-RPC batch line. Wallets (Sparrow) batch their whole gap-limit window of subscribes at scan time. |
electrummaxbroadcastpackagetxs | 25 | restart | satd | Max txs per blockchain.transaction.broadcast_package. |
electrumfeehistogramttl | 10 | restart | satd | TTL (seconds) for the mempool.get_fee_histogram cache. |
electrumbanner | powered by satd <ver> | restart | satd | Override for server.banner. |
electrumservername | satd-electrs-compatible/<ver> | restart | satd | Name reported by server.version and server.features.server_version. The default carries an electrs compatibility token because Electrum clients feature-detect by matching on this string (Cake Wallet probes silent-payment tweaks only when it contains electrs). Affects the Electrum surface only — the P2P user agent stays /satd:<ver>/. |
stratum | off | restart | satd | Run the Stratum V1 solo-mining server. Refused on signet. See Stratum Mining Server. |
stratumbind | 127.0.0.1:3333 | restart | satd | Bind the plaintext Stratum listener. A non-loopback address needs stratumtlsbind or stratumallowplaintextremote=1. |
stratumtlsbind | none (conventional port 4333) | restart | satd | Bind the Stratum TLS listener (requires cert+key). |
stratumtlscert | none | restart | satd | PEM TLS certificate (or full chain) for the Stratum server. |
stratumtlskey | none | restart | satd | PEM TLS private key for the Stratum server. |
stratummtls | false | restart | satd | Require mutual TLS on the Stratum TLS listener. |
stratummtlsclientca | none | restart | satd | PEM CA bundle to verify client certs when stratummtls=1. |
stratummtlsclientallow | any CA-signed | restart | satd | Allowlist of accepted client-cert CN/DNS-SAN values. |
stratumaddress | none | restart | satd | Payout address for a miner whose username is not a valid address for this network. |
stratumdifficulty | 10000 mainnet, 1000 testnet, 1 regtest | restart | satd | Initial Stratum share difficulty. |
stratummaxconns | 64 | restart | satd | Hard cap on simultaneous Stratum connections across both listeners. |
stratumallowplaintextremote | false | restart | satd | Accept a non-loopback stratumbind with no TLS listener. |
stratumv2bind | none | restart | satd | Bind the Stratum V2 listener (Noise-encrypted; requires stratum=1). |
stratumv2key | <datadir>/stratum_v2.key | restart | satd | Stratum V2 authority key file, created if absent. Back it up with the datadir: miners pin the key. |
stratumv2maxchannels | 16 | restart | satd | Channels one Stratum V2 connection may open. |
stratumv2jd | false | restart | satd | Serve Stratum V2 Job Declaration on the V2 listener (requires stratumv2bind). |
Storage / pruning / reindex
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
prune | 0 (no pruning) | restart | core | Prune block data to target size in MB. |
reindex | off | restart | core | Rebuild block index and chain state from block files on disk. |
reindexchainstate | off | restart | core | Rebuild the UTXO set from existing block files (Core -reindex-chainstate). |
checkblockindex | off (on for regtest) | restart | core | Audit block-index / active-chain consistency at startup (Core -checkblockindex). |
dbcache | 450 MB (or auto) | restart | core | Total write-cache size in MB, or auto for adaptive sizing. |
storageprofile | ssd | restart | satd | Storage class for chainstate tuning: ssd or hdd. |
prefetchworkers | CPU cores | restart | satd | Number of IBD prefetch worker threads. |
maxahead | 50000 | restart | satd | Max blocks ahead during IBD: number, N%, or all. |
maxopenfiles | 2048 | restart | satd | RocksDB max_open_files cap; -1 = unlimited. |
rocksdbbackgroundjobs | from storageprofile | restart | satd | Override RocksDB max_background_jobs (advanced). |
rocksdbsubcompactions | from storageprofile | restart | satd | Override RocksDB max_subcompactions (advanced). |
rocksdbwalmb | from storageprofile | restart | satd | Override RocksDB max_total_wal_size in MB (advanced). |
compactiondiagintervalsecs | 60 (0 disables) | restart | satd | Per-CF pending-compaction diagnostic log interval. |
compactionintervalsecs | 1800 (0 disables) | restart | satd | Periodic forced-compaction interval in seconds. |
compactionl0at | 16 | restart | satd | Force chainstate compaction when L0 SST count ≥ N. |
ibdl0pauseat | 64 (0 disables) | restart | satd | Pause the IBD connector when chainstate L0 SST count ≥ N. |
stallwatchdogsecs | 300 (0 disables) | restart | satd | Stall-watchdog forensic-dump threshold (seconds without tip advance). |
stallabortsecs | 300 | restart | satd | Additional grace after the forensics dump before abort(). |
shadowqueuesize | 4194304 | restart | satd | Shadow-verification queue capacity. |
shadowworkers | 4 | restart | satd | Shadow-verification worker threads. |
Mining
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
blockmaxweight | 4000000 | restart | core | Maximum block weight for templates. |
blockmintxfee | 1 sat/kvB | restart | core | Minimum fee rate for a transaction (judged with its package) to enter the block template. A bare integer is sat/kvB; a decimal is BTC/kvB, Bitcoin Core's spelling (0.00001 = 1000 sat/kvB). |
par | unset | restart | core | Script-verification threads (Core name). When shadowworkers is unset, a positive value sets the shadow-verification worker count. It does not size the connect path. |
Events
(satd-specific event bus. The eventszmq* spelling is satd's; Core uses
per-topic -zmqpub*=<addr> flags. The hashtx/hashblock payloads are
Core ZMQ wire-format compatible.)
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
eventsnodeid | auto (persisted to <datadir>/node_id) | restart | satd | Stable per-node identifier (32-char hex) stamped on events envelopes. |
eventsregion | none | restart | satd | Optional region tag (≤8 ASCII bytes) on events envelopes. |
eventsgrpcbind | off | restart | satd | host:port to bind the events gRPC streaming server. |
eventsgrpcallowremote | false | restart | satd | Permit eventsgrpcbind on a non-loopback address (requires eventsgrpcauth or eventsgrpcmtls; with eventsgrpcauth, also requires eventsgrpctlscert/eventsgrpctlskey so the bearer token is never sent in cleartext). |
eventsgrpcauth | false | restart | satd | Require bearer tokens (stream:subscribe) on events gRPC (requires authfile). |
eventsgrpcmaxconns | 64 (0 disables) | restart | satd | Hard cap on simultaneously-open events gRPC connections. |
eventsgrpcmaxsubscriptions | 256 (0 disables) | restart | satd | Hard cap on concurrent events gRPC Subscribe streams. |
eventsgrpctlscert | off | restart | satd | PEM TLS certificate. Set with eventsgrpctlskey to terminate TLS in-process on the eventsgrpcbind listener (no separate TLS bind). |
eventsgrpctlskey | off | restart | satd | PEM TLS private key (required with eventsgrpctlscert). |
eventsgrpcmtls | false | restart | satd | Require mutual TLS (client certificates). Requires eventsgrpctlscert/key and eventsgrpcmtlsclientca. |
eventsgrpcmtlsclientca | off | restart | satd | PEM CA bundle verifying client certs when eventsgrpcmtls=1. |
eventsgrpcmtlsclientallow | empty (any CA-signed cert) | restart | satd | Allowlist of accepted client-cert CN / DNS-SAN values (repeatable, comma-separated). Requires eventsgrpcmtls=1. |
eventsgrpctlshandshaketimeout | 30 | restart | satd | Per-handshake timeout (seconds) for the events gRPC TLS surface. |
streamws | off | restart | satd | host:port for the streaming JSON-over-WebSocket + SSE transport (/ws + /sse). |
streamwsallowremote | false | restart | satd | Permit streamws on a non-loopback address (requires streamwsauth). |
streamwsauth | false | restart | satd | Require bearer tokens (stream:subscribe) on streamws (requires authfile). |
streamwsmaxconns | 256 | restart | satd | Hard cap on simultaneously-open streamws connections. |
streamwsmaxsubscriptions | 256 | restart | satd | Hard cap on watch-set entries per streamws connection. |
streamwsmaxmessagebytes | 262144 | restart | satd | Cap on a single inbound WebSocket message/frame in bytes. |
streammaxresyncblocks | 10000 (0 disables) | restart | satd | Max blocks the watch matcher re-scans in one catch-up after lagging. |
streamprefixminbits | 8 | restart | satd | Minimum bit-length for a privacy-preserving script-prefix watch. |
streamprefixmaxbits | 32 | restart | satd | Maximum bit-length for a script-prefix watch (range [min, 32]). |
eventszmqbind | off | restart | satd | ZMQ endpoint for the events PUB sink. |
eventszmqhashtx | on when bound | restart | satd | Enable the Core wire-format hashtx topic. |
eventszmqhashblock | on when bound | restart | satd | Enable the Core wire-format hashblock topic. |
eventszmqmpevict | on when bound | restart | satd | Enable mpevict topic (mempool eviction w/ reason; JSON). |
eventszmqmpreplace | on when bound | restart | satd | Enable mpreplace topic (RBF replacement; JSON). |
eventszmqmpconfirm | on when bound | restart | satd | Enable mpconfirm topic (mempool tx confirmed; JSON). |
eventszmqnodeevent | on when bound | restart | satd | Enable nodeevent topic (full envelope JSON). |
Webhooks / notifications
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
blocknotify | none | restart | core | Shell command run on each new best block; %s is replaced by the block hash. Commands run serially on a dedicated subscriber task; a slow hook never stalls block connection, because notifications coalesce instead. The command body is not logged (it may embed credentials). |
alertnotify | none | restart | core | Shell command run on each new node warning; %s is replaced by the warning text. Deduped by warning id (a repeated condition fires once, not per repeat). One-shot events such as deep_reorg have no standing condition to dedupe, so they are rate-limited instead: one exec per minute per event id, reporting the worst occurrence in the window rather than the first. Runs serially like blocknotify. See Observability → Node-health alerts. |
startupnotify | none | restart | core | Shell command run once after the node finishes starting up (no %s). Detached, so a slow hook does not delay startup. Prefer a systemd ExecStartPost=. |
shutdownnotify | none | restart | core | Shell command run once at the start of a graceful shutdown, before the final flush (no %s). Bounded by maxshutdownsecs so a hung hook can't wedge teardown. Prefer a systemd ExecStopPost=. |
reorgwebhook | none | hot | satd | HTTP(S) endpoint receiving a POST on reorg detection. |
reorgwebhooksecret | none | hot | satd | HMAC-SHA256 secret signing webhook bodies via X-Satd-Signature. |
Health alerts
Thresholds for the node-health detectors. Each raises a status event on the
Streaming Consumption API and an entry in getwarnings (which
also fires alertnotify) when its condition is entered, and retracts both when
it recovers. Every one is hot-reloadable — retuning an alert should not need a
restart, since you are usually retuning it because it is firing.
Set a threshold to 0 to disable that detector. See
Observability → Node-health alerts for
the taxonomy and the details each event carries.
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
alertfile | none | path restart, contents hot | satd | TOML file describing outbound alert webhooks. Must be mode 0600 — it holds signing secrets. The path is read once at startup; the file's contents are re-read on every SIGHUP, so a hook can be added, edited, or removed live. A parse error keeps the last-good hook set. See Observability → Alert webhooks. |
alerttipstallseconds | 3600 (0 on regtest) | hot | satd | Raise tip_stall after this many seconds with no connected block. Defaults to disabled on regtest only, where blocks exist just when a test mines them and an idle chain is normal; every other network — test networks included — keeps the hour, since going an hour without a block is not an ordinary property of thin hashrate the way a shallow reorg is. Not suppressed during initial block download — is_initial_block_download() compares the tip header's timestamp against the wall clock rather than tracking sync progress, so a node that was caught up and then wedged re-enters it precisely when you need paging. A node that is genuinely syncing connects blocks continuously and so never crosses the threshold. Cleared the moment a block connects — or, if you raise this value past the current tip age, on the next detector poll. |
alertdiskfreemb | 10240 | hot | satd | Raise disk_low below this many MiB free on the blocks directory (or the data directory when blocksdir is not split out). Clears at 1.5× the floor, or as soon as you lower the floor below the current reading. |
alertmempoolfullpct | 90 | hot | satd | Raise mempool_congested at this percentage of maxmempool. Clears below 75 % of the raise line, or as soon as you raise the threshold above the current occupancy. Values above 100 are clamped. |
alertpeerfloor | 3 (0 on regtest; capped by the -connect= count) | hot | satd | Raise peer_floor below this many connected peers (inbound + outbound). The count must hold for 60 s in either direction, so ordinary peer churn does not page you, and it does not raise until 90 s after startup or the first peer, whichever is sooner. Defaults to disabled on regtest only, where a node with no peers is normal; signet keeps the floor — set alertpeerfloor=0 explicitly on a deliberately isolated signet node. When connect= is set the default drops to that many peers (never above 3), since connect= suppresses DNS and fixed seeds and the node can never exceed the addresses you named — an explicit value here still overrides it. |
alertreorgdepth | 3 (10 on test networks, 0 on regtest) | hot | satd | Emit the one-shot deep_reorg event for a reorg that rolls back at least this many blocks. Depth 3 is an incident on mainnet and ordinary on a chain with thin, volatile hashrate, so signet/testnet/testnet4 default to 10 — above the 6-confirmation convention, so a reorg that invalidated something a wallet called final still reports. Regtest defaults off: its test suites reorg deliberately. |
Note. The
*notifyshell hooks (blocknotify,alertnotify,startupnotify,shutdownnotify) exist for drop-in Bitcoin Core compatibility and quick scripts. They are best-effort shell execs with no delivery guarantee, no replay, and no reorg awareness. To build on satd, use the Streaming Consumption API (gRPC, WebSocket, or ZMQ): it is reorg-safe, offers durable cursor replay, and is decoupled from consensus. For lifecycle actions, prefer your service manager (systemdExecStartPost=/ExecStopPost=). satd honors these four hooks. Onlywalletnotifyis unsupported: satd is keyless, so watch scripts via the streaming or Esplora API. A node started with any of these hooks logs this guidance at startup.
MCP
(satd-specific; Model Context Protocol server.)
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
mcp | off | restart | satd | Enable the MCP server. |
mcpport | none | restart | satd | Enable the MCP HTTP transport on this port. |
mcpbind | 127.0.0.1 | restart | satd | MCP HTTP bind address (non-loopback requires auth + TLS). |
mcpcert | none | restart | satd | PEM TLS certificate for the MCP server (enables HTTPS; requires mcpkey). Required for any non-loopback bind. |
mcpkey | none | restart | satd | PEM TLS private key for the MCP server (requires mcpcert). |
mcpmtls | false | restart | satd | Require mutual TLS on the MCP listener (requires mcpcert/mcpkey + mcpmtlsclientca). |
mcpmtlsclientca | none | restart | satd | PEM CA bundle that client certs must chain to when mcpmtls. |
mcpmtlsclientallow | any | restart | satd | Allowlist of accepted client-cert CN / DNS-SAN values. |
mcpauth | false | restart | satd | Require bearer tokens (mcp:*) on the MCP HTTP server (requires authfile). |
mcpallowremote | false | restart | satd | Permit a non-loopback MCP HTTP bind (requires mcpauth + TLS). |
mcpallowedhost | loopback only | restart | satd | Extra Host values the MCP listener accepts, as host or host:port (repeatable, comma-separated). Loopback names are always accepted. Required to reach MCP by hostname. |
Metrics / health
| Key | Default | Reload | Compat | Description |
|---|---|---|---|---|
metricsport | none | restart | satd | Enable Prometheus /metrics + /healthz + /readyz on this port (unauthenticated). |
metricsbind | 127.0.0.1 | restart | satd | Metrics/health HTTP bind address. |
metricstlsbind | none | restart | satd | Also serve the metrics/health endpoints over TLS on this addr:port (requires metricsport, cert and key). |
metricstlscert | none | restart | satd | PEM certificate for the metrics TLS listener. |
metricstlskey | none | restart | satd | PEM private key for the metrics TLS listener. |
metricsmtls | false | restart | satd | Require a client certificate on the metrics TLS listener (requires metricsmtlsclientca). |
metricsmtlsclientca | none | restart | satd | PEM CA bundle client certs must chain to when metricsmtls=1. |
metricsmtlsclientallow | any | restart | satd | Allowlist of accepted client-cert CN / DNS-SAN values on the metrics TLS listener. |
statuspage | 0 | restart | satd | Serve the status page at /status, /status.json and /status.js on the metrics listener. Requires metricsport. |
statusadvertise | none | restart | satd | Repeatable, one per surface. <surface>=<url>, where surface is electrum, esplora, rpc or mcp: a connection string the status page shows, e.g. electrum=ssl://node.local:50002. |
Unsupported Core keys: skipped vs rejected
A Core v30 option satd doesn't honor is handled
one of two ways so that an existing bitcoin.conf still drops in.
Skipped with a warning (the node still starts)
Recognized Core v30 options satd doesn't implement, but that are safe to skip,
are ignored with a startup WARN line; the node boots without them. The
warning names the satd equivalent where one exists. This covers the long tail:
| Key(s) | Warning guidance |
|---|---|
rest | satd ships native Esplora REST instead of Core's /rest/; enable with -esplora (on by default). |
zmqpub* (hashtx/hashblock/rawtx/rawblock/sequence + *hwm) | Core's per-topic ZMQ is replaced by the events bus (-eventszmqbind + -eventszmqhashtx/-eventszmqhashblock, Core wire-format). |
peerbloomfilters | BIP37 unsupported (privacy/DoS); use BIP157/158 (-blockfilterindex/-peerblockfilters). |
natpmp | satd doesn't implement PCP/NAT-PMP port mapping; configure port forwarding externally. (upnp was removed in Core v29 and is rejected as unknown, as in Core v30.) |
debuglogfile, shrinkdebugfile, printtoconsole, logratelimit | satd logs to stdout/journald; no debug.log. |
logtimemicros | satd's logger always emits sub-second timestamps; there is no seconds-only mode, so the option has no effect. Use -logtimestamps=0 to drop timestamps entirely. |
maxorphantx | Removed in Core v30 too. |
wallet, walletdir, walletnotify, … | satd is keyless (no wallet); use external wallets + PSBT, and watch scripts via the streaming/Esplora API. |
coinstatsindex, loadblock, checkblocks/checklevel, bytespersigop, maxsigcachesize, blockversion, printpriority, txreconciliation, discover, persistmempoolv1, acceptstalefeeestimates, settings, daemonwait, deprecatedrpc, rpcdoccheck, … | Recognized Core v30 options satd does not implement; skipped (generic warning). |
Rejected at load (fail-closed)
A small set stays fatal, because silently skipping them would mislead you about the node's security, exposure, or privacy posture. Each rejects with an actionable message:
| Key(s) | Reason |
|---|---|
i2psam, i2pacceptincoming | I2P is out of scope; skipping would route traffic over clearnet instead of the privacy network you configured. Tor is satd's anonymity network (-proxy/-onion/-torcontrol). |
rpcwhitelist, rpcwhitelistdefault | satd uses capability-scoped bearer tokens (-authfile); skipping would leave RPC less restricted than your Core config intends. See Authentication & Authorization. |
Typos
A key that is neither a satd option nor a known Core v30 option is rejected at
load as a likely typo. This is what stops a mistyped rpcusser= from silently
disabling authentication. The same rule catches Core v31+ keys: the
compatibility surface is frozen at v30, so a key Core only added later is
treated as unknown until the pin is bumped.
Note. "Supported" means the commonly used Core v30 operator surface, with semantics pinned to Core v30 (not later releases). The long tail is skipped with a warning rather than honored. To consume node events from your own software, use the Streaming Consumption API instead of the
*notifyhooks or RPC polling.