Summary
On Ubuntu Core the snap cannot resolve DNS, so cloudflared exits immediately and systemd restart-loops the service until it gives up. Host DNS is healthy throughout — only the snap is affected.
Environment
charmed-cloudflared 2026.5.0 (rev 77), latest/stable, arm64
- Ubuntu Core 26 (base
core26), snapd 2.76, Raspberry Pi 5
- Host resolution works:
resolvectl query snapcraft.io succeeds; systemd-resolved stub on 127.0.0.53
Symptom
ERR edge discovery: error looking up Cloudflare edge IPs: the DNS query failed
error="lookup _v2-origintunneld._tcp.argotunnel.com on [::1]:53: read udp [::1]:45135->[::1]:53: read: connection refused"
ERR Initiating shutdown error="Could not lookup srv records on _v2-origintunneld._tcp.argotunnel.com: ..."
subprocess.CalledProcessError: Command '['/snap/charmed-cloudflared/77/usr/bin/cloudflared', 'tunnel', '--no-autoupdate', '--metrics', '127.0.0.1:39000', '--protocol', 'http2', 'run']' returned non-zero exit status 1.
systemd[1]: snap.charmed-cloudflared.cloudflared.service: Start request repeated too quickly.
Cause
charmed-cloudflared-snap/snap/snapcraft.yaml declares (still present at HEAD):
layout:
/etc:
bind: $SNAP_DATA/etc
This replaces the whole of /etc inside the snap's mount namespace with $SNAP_DATA/etc, which is empty on a fresh install. The base's /etc/resolv.conf (a symlink to ../run/systemd/resolve/stub-resolv.conf) is therefore masked:
$ sudo snap run --shell charmed-cloudflared.cloudflared -c 'cat /etc/resolv.conf'
cat: /etc/resolv.conf: No such file or directory
$ sudo snap run --shell charmed-cloudflared.cloudflared -c 'stat -c %n /run/systemd/resolve/stub-resolv.conf'
/run/systemd/resolve/stub-resolv.conf
The symlink target is reachable inside the namespace; only /etc/resolv.conf itself is missing.
cloudflared is a Go binary, and with no /etc/resolv.conf Go's resolver falls back to localhost:53. On Ubuntu Core nothing listens there — systemd-resolved binds 127.0.0.53 and 127.0.0.54 — so every lookup fails with connection refused, including the SRV lookup for edge discovery.
Nothing in the snap creates the file: the only hook is configure, and the sole reference to resolv anywhere in the snap is inside the cloudflared binary itself.
$ ls -A /var/snap/charmed-cloudflared/current/etc/ # empty on a fresh install
$ ls /snap/charmed-cloudflared/current/meta/hooks/
configure
For comparison, a snap on a core22 base without an /etc layout (e.g. node-red) sees the symlink normally and resolves fine on the same host, which is what narrowed this down to the layout rather than to confinement or to Ubuntu Core itself.
Workaround
Create the file the layout leaves missing:
printf 'nameserver 127.0.0.53\nnameserver 1.1.1.1\nnameserver 1.0.0.1\n' \
| sudo tee /var/snap/charmed-cloudflared/current/etc/resolv.conf
sudo snap restart charmed-cloudflared
The tunnel then registers all four connections normally and survives reboots.
Suggested fix
Any of:
- Seed a default
resolv.conf into $SNAP_DATA/etc from an install hook — e.g. a symlink to /run/systemd/resolve/stub-resolv.conf, or a small file with the stub plus a public fallback.
- Narrow the layout to the specific paths the snap needs under
/etc rather than binding all of /etc.
- If the current behaviour is intended, document that
$SNAP_DATA/etc/resolv.conf must be provided by the operator.
Happy to test a fix on Ubuntu Core.
Still current
Checked against main: charmed-cloudflared-snap/snap/snapcraft.yaml still carries the /etc layout, and charmed-cloudflared-snap/snap/hooks/configure only normalises snap options and restarts the service — nothing creates $SNAP_DATA/etc/resolv.conf.
Summary
On Ubuntu Core the snap cannot resolve DNS, so
cloudflaredexits immediately and systemd restart-loops the service until it gives up. Host DNS is healthy throughout — only the snap is affected.Environment
charmed-cloudflared2026.5.0 (rev 77),latest/stable, arm64core26), snapd 2.76, Raspberry Pi 5resolvectl query snapcraft.iosucceeds; systemd-resolved stub on127.0.0.53Symptom
Cause
charmed-cloudflared-snap/snap/snapcraft.yamldeclares (still present at HEAD):This replaces the whole of
/etcinside the snap's mount namespace with$SNAP_DATA/etc, which is empty on a fresh install. The base's/etc/resolv.conf(a symlink to../run/systemd/resolve/stub-resolv.conf) is therefore masked:The symlink target is reachable inside the namespace; only
/etc/resolv.confitself is missing.cloudflaredis a Go binary, and with no/etc/resolv.confGo's resolver falls back tolocalhost:53. On Ubuntu Core nothing listens there — systemd-resolved binds127.0.0.53and127.0.0.54— so every lookup fails withconnection refused, including the SRV lookup for edge discovery.Nothing in the snap creates the file: the only hook is
configure, and the sole reference toresolvanywhere in the snap is inside thecloudflaredbinary itself.For comparison, a snap on a
core22base without an/etclayout (e.g.node-red) sees the symlink normally and resolves fine on the same host, which is what narrowed this down to the layout rather than to confinement or to Ubuntu Core itself.Workaround
Create the file the layout leaves missing:
The tunnel then registers all four connections normally and survives reboots.
Suggested fix
Any of:
resolv.confinto$SNAP_DATA/etcfrom an install hook — e.g. a symlink to/run/systemd/resolve/stub-resolv.conf, or a small file with the stub plus a public fallback./etcrather than binding all of/etc.$SNAP_DATA/etc/resolv.confmust be provided by the operator.Happy to test a fix on Ubuntu Core.
Still current
Checked against
main:charmed-cloudflared-snap/snap/snapcraft.yamlstill carries the/etclayout, andcharmed-cloudflared-snap/snap/hooks/configureonly normalises snap options and restarts the service — nothing creates$SNAP_DATA/etc/resolv.conf.