#36434 http: support unix sockets

ReviewabilityReviewsAgreementSize
#36434 pinheadmz http: support unix socketsReady0Strong754 + 793 tests
  • Allow local RPC and REST connections and bitcoin-cli over UNIX domain sockets
  • Lets node operators manage access via filesystem permissions rather than IP allowlists
  • Eliminates TCP loopback overhead for local node communication
  • Ready to review
  • Approach approval citing clean design with socket variants and high user demand (winterrdog)
  • Concept approval without stated reasons (b-l-u-e)
  • Earlier concerns regarding socket file collisions and Host header regressions were fixed (b-l-u-e)
  • Open question on whether to support abstract namespace sockets in the future (winterrdog)
  • 754 lines added or modified outside tests
  • 793 lines added or modified in tests
  • 265 lines removed in total
  • 20 files, 10 commits
RPC / REST / ZMQ#6 of 55
P2 · user request
  • P2 because it fulfills a long-standing user request for UNIX domain socket RPC support
  • Provides filesystem-based access control and removes TCP loopback overhead for node operators
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Adds UNIX domain socket support to Bitcoin Core's HTTP RPC server and bitcoin-cli via the -rpcbind and -rpcconnect configuration options using unix and unix:<path> syntax. It introduces UnixSocketAddr and a SocketAddr variant in netbase to decouple generic endpoint handling from P2P-specific networking classes like CService, and updates Proxy and HTTPServer accordingly. When binding exclusively to UNIX domain sockets, -rpcallowip is no longer required and default TCP loopback listeners are disabled.

Problem: Local JSON-RPC and REST communication previously required TCP loopback connections, forcing node operators to manage IP-based allowlists instead of operating system filesystem permissions and incurring TCP stack overhead. Additionally, earlier UNIX socket support added in PR #27375 was isolated to the Proxy class, leaving technical debt where socket abstractions were tangled with P2P networking classes.

Evidence of importance:

  • Closes issue #5029, an open feature request for UNIX domain socket support in RPC since 2014.
  • Description notes that earlier UNIX socket support in #27375 created technical debt in Proxy that this PR resolves with generic abstractions.

Scope: Refactors networking abstractions across netbase and httpserver by replacing CService with SocketAddr (a std::variant of CService and UnixSocketAddr) in HTTPRemoteClient and Proxy. Includes substantial new unit tests in src/test/netbase_tests.cpp (+498 lines) and functional test framework support via --httpunix.

Risk of a mistake: medium (rpc_api, tooling, tests, docs). A mistake in socket path resolution or socket binding permissions could prevent local RPC access or inadvertently expose the RPC interface to unauthorized local users.

Changed since the previous assessment: Added release notes and documentation for JSON-RPC, and extended functional test coverage for bitcoin-cli over UNIX domain sockets in interface_bitcoin_cli.py and test_runner.py.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • author: winterrdog's question about abstract sockets and suggestion to update the PR description 2026-10-16

Agreement

Strong

substantive support, no open objection (winterrdog, winterrdog)

Thread notes: Added hodlinator as a participant and recorded their question about the benefit of HTTP over unix sockets vs IPC, which was answered by pinheadmz. A typo remark in rc:4412188649 was omitted as a nit.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
b-l-u-e (contributor)objection, correctnessA second node started with the same -rpcbind=unix:<path> will overwrite the live socket file without error, making the first node unreachable while it remains running.fixed · fix pushed · author pushed changes adopting ipcbind parameter format to make sockets datadir-scoped by defaultchangedyes2026-10-05: 'second node can take over a live rpc unix socket path, if two nodes use different datadirs but the same -rpcbind=unix:<path> the second node starts with no error..since it removes the first node socke'
Status from: 2026-10-08: pinheadmz: 'This should also adderss @b-l-u-e concern about multiple processes messing with each others sockets.'
b-l-u-e (contributor)objection, interfacebitcoin-cli sends the resolved IP in the HTTP Host header instead of the hostname passed via -rpcconnect=, introducing a behavior change/regression from master.fixed · fix pushed · author pushed fix for Host header in bitcoin-clichangedyes2026-10-05: 'the host header contains the resolved IP instead of the hostname given in `-rpcconnect=localhost`'
Status from: 2026-10-08: pinheadmz: 'fix `"Host:` header in bitcoin-cli (@b-l-u-e)'
winterrdog (contributor)objection, correctnessOn platforms where char is signed, non-ASCII UTF-8 bytes wrap to negative values and match c < 0x20, causing valid UTF-8 paths like /tmp/josé.sock to be replaced with "unix" in logs.fixed · fix pushed · author fixed using unsigned char and std::ranges in push e34ffb6de9changedyes2026-10-11: 'char is signed on some platforms (e.g. x86), so bytes above 0x7f are interpreted as negative values (they wrap around) and also match c < 0x20. this means a utf-8 path like /tmp/josé.sock could end up'
Status from: 2026-10-28: pinheadmz: 'good suggestion thanks, using `std::ranges` and `unsigned char` here'
winterrdog (contributor)suggestion, approachPlace Unix socket handling code behind an #ifdef HAVE_SOCKADDR_UN guard to avoid compiling unused code on unsupported platforms.fixed · fix pushed · author added compile guard in push e34ffb6de9answeredyes2026-10-14: 'why don't we just put this behind an #ifdef HAVE_SOCKADDR_UN guard so we skip this code entirely on platforms that do not support unix sockets ?'
Status from: 2026-10-28: pinheadmz: 'yep fair enough, putting behind a compile guard'
winterrdog (contributor)suggestion, interfaceLog host instead of strRPCBind in the bind failure warning to avoid redundant port strings when a port is included in the address.fixed · fix pushed · author resolved this along with the GetBindAddresses refactoransweredyes2026-10-15: 'strRPCBind can show up in the logs if the optional port is included in the bind address (e.g. 127.0.0.1:8332), leading to logs like this one: Could not bind RPC on address 127.0.0.1:8332 port 8332: Ad'
Status from: 2026-10-28: pinheadmz: 'fixed this along with the `GetBindAddresses()` refactor.'
winterrdog (contributor)question, correctnessWhether duplicate -rpcbind unix socket endpoints unlinking the earlier socket and rebinding silently without warning is intended behavior or should fail like TCP.answered · author replied that duplicate binds are considered an acceptable edge caseansweredyes2026-10-15: 'if two -rpcbind values resolve to the same path (e.g. -rpcbind=unix and -rpcbind=unix:http.sock, or the same value in bitcoin.conf and perhaps on the command line), PreparePath() (later called in HTTP'
Status from: 2026-10-28: pinheadmz: 'Heh that's kind of a funny edge case. We don't complain if a user sets `-rpcport=50000` twice for example. I think it's '
winterrdog (contributor)question, scopeWhether abstract namespace unix sockets should be supported in the future for Linux-specific setups.openansweredno2026-10-16: 'i saw UnixSocketAddr::SetSockAddr() handles empty and abstract namespace addresses, but we do not support binding or connecting to abstract sockets. do you think it is worth supporting them in the fut'
winterrdog (contributor)suggestion, maintenanceUpdate the PR description to match the code regarding Unix socket path resolution.openansweredno2026-10-16: 'the docs, release notes and -help text already match the code, so i think the PR description just needs updating to reflect this, so other reviewers do not get tripped up by the mismatch'
winterrdog (contributor)suggestion, maintenanceRefactor GetBindAddresses() to reduce cognitive load and streamline the control flow.fixed · fix pushed · author adopted the suggested refactor with tweaks in push e34ffb6de9answeredyes2026-10-16: 'while reviewing GetBindAddresses(), i ended up rewriting it to lower the cognitive load a bit and help me get my head around the flow. thought i could share it and see what you think'
Status from: 2026-10-28: pinheadmz: 'I think it's a good idea to clean this up now, thanks. Taking the suggestion and tweaking a bit more on top (comments an'
hodlinator (member)question, usefulnessWhat is the benefit of allowing HTTP over unix sockets compared to using IPC over unix sockets, given executeRpc() is already exposed through IPC?answered · author explained that unix sockets do not require capnproto or multiprocess mode and have a lower barrier to entryansweredyes2026-10-29: 'What is the benefit of allowing HTTP over unix sockets compared to using IPC over unix sockets?'
Status from: 2026-10-29: pinheadmz: 'You get the security advantage and possibly an efficiency advantage with a very low bar for entry. IPC requires capnproto, unix sockets only require platform support.'

Support:

  • winterrdog (contributor) (Concept ACK, 2026-10-04) [read]: users of other projects relying on Core have wanted Unix domain socket support, and previous libevent blockers are gone
  • b-l-u-e (contributor) (Concept ACK, 2026-10-05): (no reason given) [not substantive]
  • winterrdog (contributor) (Approach ACK, 2026-10-16) [read]: convinced by the implementation and design choices, particularly using std::variant over polymorphism for SocketAddr; security is tight

Participants:

  • winterrdog (contributor, objection, 12 statements 2026-10-04 to 2026-10-16): Approach ACK; raised signed char bug (fixed), suggestions on compile guard and refactoring, and questions
  • b-l-u-e (contributor, objection, 2 statements 2026-10-05 to 2026-10-05): Concept ACK; reported socket takeover on collision and Host header regression (both fixed)
  • hodlinator (member, question, 2 statements 2026-10-29 to 2026-10-29): asked about the benefits of HTTP over unix sockets compared to IPC

Files

857 lines under test/bench/ci.

  • src/test/netbase_tests.cpp +498/-0
  • src/netbase.cpp +203/-25
  • src/netbase.h +190/-16
  • src/bitcoin-cli.cpp +133/-55
  • src/httpserver.cpp +108/-51
  • test/functional/rpc_bind.py +124/-7
  • src/init.cpp +67/-43
  • test/functional/interface_http.py +64/-17
  • test/functional/interface_bitcoin_cli.py +45/-27
  • doc/release-notes-36434.md +31/-0
  • test/functional/test_framework/test_node.py +22/-2
  • src/httpserver.h +9/-10
  • test/functional/test_framework/netutil.py +15/-0
  • src/test/httpserver_tests.cpp +7/-7
  • doc/JSON-RPC-interface.md +12/-0
  • test/functional/test_framework/authproxy.py +7/-3
  • test/functional/test_framework/test_framework.py +7/-0
  • test/functional/test_runner.py +3/-0
  • src/qt/clientmodel.cpp +1/-1
  • src/test/fuzz/http_request.cpp +1/-1

Card

The short text the ranking pass compares across PRs.

Adds UNIX domain socket support to the HTTP RPC server and bitcoin-cli using -rpcbind=unix[:path] and -rpcconnect=unix[:path]. This enables local RPC communication without TCP loopback overhead, relying on filesystem permissions instead of -rpcallowip. The PR also refactors netbase by introducing UnixSocketAddr and SocketAddr, resolving technical debt left from PR #27375. This closes issue #5029, a feature request open since 2014.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-30T01:14, confidence high, input hash 427ca2e06f0bcf7c
thread read through 2026-10-29 (34 statements), head ccbace1c33
labels: RPC/REST/ZMQ

Categories

RPC / REST / ZMQ

P2 · user request

Closes a decade-old feature request (#5029) to support UNIX domain sockets for the HTTP RPC server and bitcoin-cli. This provides substantial user value by allowing filesystem permissions instead of IP allowlists and eliminating TCP loopback overhead.

Membership: Carries the RPC/REST/ZMQ label and directly modifies src/httpserver.cpp, src/bitcoin-cli.cpp, and RPC configuration handling.

Factors: security/stability 1, bug 0, performance 1, user value 2, leverage 1