#2228·umbrel

# App installs fail intermittently in `umbrel-dev`: DNS resolution breaks after container/app lifecycle events

Author: Juwon-OgunseyeCreated Sep 12, 2026Updated Sep 12, 2026

Summary

In a local umbrel-dev (docker-based dev environment) instance, Docker image pulls inside the container intermittently fail with DNS timeouts, which in turn causes app installs to silently stall (stuck at a low percentage, then reverts to "Install") with no container ever created.

This is not a one-time setup issue — it is reproducible on demand by following a specific sequence involving uninstalling and reinstalling a community app.

Related, already-reported issues

This appears to be the same underlying category of problem as two existing reports on this repo:

  • https://github.com/getumbrel/umbrel/issues/1785 — reports that an app install can get stuck, and specifically that this "also occurs when you try to install an already installed app," with the suggested workaround being to remove all Umbrel containers and reinstall.
  • https://github.com/getumbrel/umbrel/issues/1853 — reports installs silently failing from the Umbrel Store, root-caused there to Docker image pulls failing underneath the UI, discoverable by running docker pull manually and seeing the real error the UI doesn't surface.

Both match the symptoms below closely, but neither pins down the DNS/ UDP:53-specific root cause, or the exact uninstall→reinstall trigger that makes it reproducible on demand. This report adds that concrete, minimal reproduction inside umbrel-dev specifically, plus what was and wasn't effective as a fix.

Environment

  • umbrel-dev (docker-container-based dev instance, per getumbrel/umbrel's own dev tooling)
  • Host: Ubuntu, Docker Engine (host), nested Docker daemon inside the umbrel-dev container itself
  • umbrel-dev container created via the standard npm run dev flow

Steps to reproduce

  1. Start umbrel-dev fresh (npm run dev start, or docker start umbrel-dev on an existing instance).
  2. Confirm baseline: docker exec umbrel-dev docker pull hello-world succeeds.
  3. Install any community app (e.g. Bitcoin Node) through the dashboard — this succeeds.
  4. Uninstall that same app through the dashboard.
  5. Attempt to reinstall it (or install a different app) immediately after.
  6. Observe: the install progress bar advances to some low percentage (varies: 1%, 4%, 30% observed across different attempts) and then silently reverts to the "Install" button. No error is shown in the UI.
  7. Confirm no container was created: docker exec umbrel-dev docker ps -a | grep <app-name> returns nothing.
  8. Confirm the underlying cause: docker exec umbrel-dev docker pull hello-world now fails with:
    Error response from daemon: Get "https://registry-1.docker.io/v2/":
    dial tcp: lookup registry-1.docker.io on <dns-server>:53: read udp
    ...: i/o timeout

What we confirmed about the root cause

  • Raw network connectivity from the container is fine (ping 8.8.8.8 succeeds).
  • Plain system-level DNS resolution works (getent hosts registry-1.docker.io returns valid IPv6 addresses).
  • Those IPv6 addresses are unreachable from the container specifically (curl -6 https://registry-1.docker.io/v2/ → "Network is unreachable"), while IPv4 (curl -4) connects immediately.
  • DNS-over-HTTPS (port 443) works reliably; plain UDP:53 queries (what Docker's own resolver uses) consistently time out, even against known-good public resolvers (8.8.8.8, 1.1.1.1).
  • This points to UDP:53 traffic specifically being dropped somewhere between the nested Docker daemon (inside umbrel-dev) and the network, rather than a broader connectivity or firewall issue.

What we tried that did NOT resolve it

  • Restarting the Docker daemon inside the container (systemctl restart docker) after changing /etc/docker/daemon.json to set explicit DNS servers (8.8.8.8, 1.1.1.1) — the resulting docker pull still timed out on the same public resolvers.
  • Disabling IPv6 at the kernel level inside the container (sysctl -w net.ipv6.conf.all.disable_ipv6=1) — did not change the outcome; the DNS query itself still timed out even over IPv4 after this change.
  • A full docker restart umbrel-dev (not a volume wipe) — this resolves the DNS issue temporarily (confirmed via a fresh docker pull hello-world succeeding right after restart), but the same failure reliably returns after the uninstall/reinstall sequence above is repeated. So a plain container restart is not a fix, only a temporary reset of whatever state gets corrupted by the uninstall/reinstall cycle.

What did work (destructive, last resort)

  • A full, clean reset — stopping and removing the container, then removing the underlying data volume entirely (docker volume rm umbrel-dev) — followed by a fresh npm run dev start, produced a working instance where docker pull succeeded immediately and the first app install completed successfully.
  • However, this is not a real fix: it discards all existing app data and state, and — critically — the same failure reproduces again as soon as the uninstall → reinstall sequence (steps 4–5 above) is repeated on this fresh instance. So the underlying trigger is not something present only in old/corrupted state; it is actively reintroduced by the normal uninstall/reinstall app lifecycle itself.

Practical, non-destructive workaround (temporary, must be reapplied)

Manually resolve the specific hostnames Docker needs via DNS-over-HTTPS and hardcode them into the container's /etc/hosts:

bash
docker exec umbrel-dev sh -c "echo 'nameserver 8.8.8.8' > /etc/resolv.conf"
docker exec umbrel-dev sh -c "curl -s --doh-url https://1.1.1.1/dns-query \
  'https://cloudflare-dns.com/dns-query?name=registry-1.docker.io&type=A' \
  -H 'accept: application/dns-json'"
# repeat for auth.docker.io and production.cloudfront.docker.com, then:
docker exec umbrel-dev sh -c "echo '<ip> registry-1.docker.io' >> /etc/hosts"

This restores docker pull immediately, but does not survive a container restart (/etc/resolv.conf and /etc/hosts both reset to defaults), and the CDN host's IP in particular has a very short TTL (30-60s) and needs re-resolving frequently.

Open question

What specifically changes, during an app uninstall/reinstall cycle, that breaks UDP:53 DNS resolution for the nested Docker daemon each time — given that a plain restart of the same container (without that cycle) does not by itself reintroduce the problem?