Repository navigation
discard the sticky disk's resolv-host.conf before buildkitd starts - #140
Merged
shreyas-blacksmith merged 2 commits intoOct 5, 2026
Merged
Conversation
BuildKit bind-mounts <root>/runc-*/executor/resolv-host.conf into every --network=host RUN and only regenerates it on the daemon's first container or when it is older than /etc/resolv.conf (boot time on our VMs). It deletes hosts and resolv.conf at startup but not this file, so on a sticky disk it survives from whichever VM last committed, naming that VM's eth0 address as nameserver. Any build whose first container is not the host-mode RUN (e.g. a # syntax= frontend) then runs host-network steps with a dead resolver and every lookup fails with EAI_AGAIN. Remove the file right after mounting the sticky disk so the daemon writes one with this VM's address.
shreyas-blacksmith
marked this pull request as ready for review
October 5, 2026 17:45
✅ Host-network RUN after sticky disk carries another VM's resolv-host.confBefore, the host-network RUN inherited the other VM's nameserver and the lookup timed out. After, the post-mount cleanup removed the file and the RUN got this VM's eth0 and resolved. ✅ 2 of 2 claims verified with evidence
Proof on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What broke
A repo's
--network=hostRUN steps can fail withgetaddrinfo EAI_AGAIN <hostname>for any external name during the image build, while the VM's own DNS works fine. It only hits VMs that had been up for a few minutes before the job started, and only Dockerfiles whose first container is not a host-network RUN (for example ones that start with# syntax=docker/dockerfile:…, which runs the frontend as a sandboxed container first).Why
BuildKit generates the
/etc/resolv.confit bind-mounts into RUN containers once and keeps it on disk under the worker root:executor/resolv.conffor sandboxed RUNs,executor/resolv-host.conffor--network=hostRUNs. We configure buildkitd withdns.nameservers = [<this VM's eth0 IP>], so the file names the VM's own address.The worker root is
/var/lib/buildkit, which is the repo's sticky disk. So the savedresolv-host.confis inherited from whichever VM last committed the disk, and it names that VM's eth0 address. From this VM that address is dead.BuildKit guards against stale files two ways, and both miss this case:
runcexecutor.Newdeletesexecutor/hostsandexecutor/resolv.confon daemon start. It does not deleteresolv-host.conf(added later for host networking).GetResolvConfregenerates on the daemon's first container of either mode. After that it reuses the saved file unless its mtime is older than/etc/resolv.conf. On our VMs/etc/resolv.confis written at boot, so a file committed by another VM after this VM booted looks fresh and is kept.With a
# syntax=frontend, the frontend container (sandboxed mode) is the daemon's first container and uses up the first-run regeneration. The first host-mode RUN then falls through to the mtime check and inherits the other VM's nameserver.flowchart LR subgraph before [Before] direction TB a1[mount sticky disk] --> a2[buildkitd starts: rm hosts, resolv.conf] --> a3[frontend container: first run, regenerate resolv.conf] --> a4[host-mode RUN: saved resolv-host.conf newer than /etc/resolv.conf, keep it] --> a5[nameserver = other VM's eth0: EAI_AGAIN] end subgraph after [After] direction TB b1[mount sticky disk] --> b2[new: rm executor/resolv-host.conf] --> b3[buildkitd starts] --> b4[frontend container: first run] --> b5[host-mode RUN: no saved file, regenerate with this VM's eth0] --> b6[lookups work] end before ~~~ afterReproduced on devbox with the
v0.29.5-blacksmithbinary: plant a bogus nameserver inresolv-host.conf, run a sandboxed step first, and the host-mode step inherits it; run the host-mode step first and it regenerates.The change
Right after
setupStickyDiskmounts the disk, remove/var/lib/buildkit/runc-*/executor/resolv-host.conf(as root, so the glob expands). Failure to remove only warns. buildkitd then writes a fresh one on the first host-mode RUN.A per-VM file should never ride along on the sticky disk. The matching fork/upstream fix is to add
resolv-host.confto the startup cleanup inruncexecutor.New; this PR is the no-roll version.Verification
pnpm eslint .,pnpm tsc --noEmit,pnpm vitest run(31 tests) andpnpm run buildpass locally;dist/is rebuilt from this source. The live action-test jobs in CI exercise the new removal on real sticky disks.