Tested on: Patroni 4.1.5, etcd 3.4.30 → 3.6.15
You installed etcd with apt, started a healthy 3-member cluster, and pointed Patroni at it. Patroni never starts PostgreSQL. It just logs the same error every five seconds. The problem is the etcd version, not your configuration.
The symptom
ERROR: Failed to get list of machines from http://127.0.0.1:2379/v3: AttributeError("'int' object has no attribute 'get'")
ERROR: Failed to get list of machines from http://127.0.0.1:2380/v3: AttributeError("'int' object has no attribute 'get'")
INFO: waiting on etcd
Meanwhile etcd itself looks perfectly healthy, which is what makes this confusing:
$ etcdctl endpoint health
127.0.0.1:2379 is healthy: successfully committed proposal: took = 2.1ms
The cause
Patroni's etcd3 backend doesn't use gRPC. It talks to etcd's JSON gateway over plain HTTP, the /v3/… endpoints. Ubuntu 24.04's etcd-server package is etcd 3.4.30. On that build, the endpoint Patroni calls first to discover cluster members doesn't answer the way Patroni expects:
$ curl -s http://127.0.0.1:2379/version
{"etcdserver":"3.4.30","etcdcluster":"3.4.0"}
$ curl -s -X POST http://127.0.0.1:2379/v3/cluster/member/list -d '{}'
404 page not found
Patroni gets back something that isn't the JSON object it expects, fails while parsing it, and retries forever. The error names a Python type, not etcd, which sends people looking in the wrong place.
The same request against etcd 3.6 returns the member list, and Patroni bootstraps immediately. We confirmed both on the same machine while testing the Twinhull kit.
Confirm it on your system
etcd --version | head -1 # 3.4.x → this is your problem
curl -s -X POST http://<etcd-ip>:2379/v3/cluster/member/list -d '{}' | head -c 200
If the second command prints 404 page not found instead of JSON with a members array, upgrade etcd.
The fix: install etcd 3.5 or newer from the official release
Distribution packages lag behind. Install the upstream release binaries, which are statically linked and have no dependencies (current as of September 2026: 3.6.15; check github.com/etcd-io/etcd/releases):
sudo systemctl disable --now etcd # stop the distro etcd
sudo apt remove -y etcd-server etcd-client
ETCD_VER=v3.6.15
curl -fsSL -o /tmp/etcd.tgz \
https://github.com/etcd-io/etcd/releases/download/$ETCD_VER/etcd-$ETCD_VER-linux-amd64.tar.gz
tar xzf /tmp/etcd.tgz -C /tmp
sudo install -m 755 /tmp/etcd-$ETCD_VER-linux-amd64/{etcd,etcdctl,etcdutl} /usr/local/bin/
etcd --version | head -1 # etcd Version: 3.6.15
Then run etcd from /usr/local/bin/etcd with your own systemd unit and a config file (--config-file /etc/etcd/etcd.conf.yml).
Upgrading an existing 3.4 cluster? etcd supports upgrading one minor version at a time: 3.4 → 3.5 → 3.6, member by member. For a new Patroni cluster that has never stored anything, it's simpler to stop all members, wipe their data directories, and start fresh on 3.6.
Two more things while you're here
-
Don't switch Patroni to the old
etcd(v2) backend to work around this. The v2 API is deprecated, and etcd 3.6 no longer serves it. -
Use
etcdctlwithout a proxy. If your servers exportHTTPS_PROXY, add the etcd addresses toNO_PROXY, or health checks may go through the proxy and time out.
Caught automatically in the Twinhull HA Kit
The kit's preflight check fails on etcd versions older than 3.5 before you install anything, and the guide installs the official 3.6 release with a hardened systemd unit and optional mutual TLS.
Originally published at twinhullhq.com. The health-check script used in these tests is free and open source: github.com/twinhullhq/ha-check. If you run Patroni in production, the full kit (templates, failover drills, DR runbook, 3-node lab) is at twinhullhq.com.












