gohugoio/hugo · error
failed to acquire a build lock
Error message
failed to acquire a build lock: %w
What it means
Returned at the very start of a build when LockBuild() cannot acquire the build mutex. The %w is the lock-acquisition error from the buildMu (a file/OS-level lock guarding the working tree).
Solutions
- Ensure no other Hugo process is running against the same project (check `ps` / `hugo --renderSegments` locks).
- Make the resources/ and working directories writable (chmod/chown).
- Remove a stale lock file under resources/_gen or the build lock path, then rebuild.
- If running embedded, pass NoBuildLock=true only for non-overlapping single-process builds.
Example fix
// before: two concurrent builds on same workdir
go func(){ _ = hugo.Build(cfg) }()
hugo.Build(cfg) // -> failed to acquire a build lock
// after: serialize builds or disable the lock for single-process use
hugo.Build(BuildCfg{NoBuildLock: true}) Defensive patterns
Strategy: validation
Validate before calling
// Ensure the work dir + resources are writable and no other Hugo process holds the lock.
if !writable(h.workingDir) { return errors.New("workdir not writable") }
if otherHugoRunning() { return errors.New("another hugo build is running") } Try / catch
unlock, err := h.BaseFs.LockBuild()
if err != nil {
if isLockHeld(err) { return fmt.Errorf("build in progress; retry later") }
return fmt.Errorf("failed to acquire a build lock: %w", err)
}
defer unlock() Prevention
- Serialize Hugo builds per project; don't run server + CLI build concurrently.
- Keep resources/ on a writable filesystem.
- Clean stale locks after a crashed build before re-running.
When it happens
Trigger: Raised at hugo_sites_build.go:97 when h.BaseFs.LockBuild() fails (b.buildMu.Lock() errors). Occurs if the lock file backing buildMu cannot be created/acquired — e.g. resources dir not writable, or a stale/corrupt lock.
Common situations: Concurrent `hugo`/`hugo server`/`hugo mod` processes racing the same project; resources/ or working dir on a read-only filesystem; a previous crashed build left a stale lock; permissions changed in CI.
Related errors
- assemble
- error building site
- error copying static files
- failed to acquire a build lock
- failed to build JS batch
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/cdd888c605a1807c.
Report an issue: GitHub.
Appendix: source
Thrown at hugolib/hugo_sites_build.go:97
}
infol := h.Log.InfoCommand("build")
defer loggers.TimeTrackf(infol, time.Now(), nil, "")
defer func() {
h.reportProgress(func() (state terminal.ProgressState, progress float64) {
return terminal.ProgressHidden, 1.0
})
h.BuildState.BuildCounter.Add(1)
}()
if h.Deps == nil {
panic("must have deps")
}
if !config.NoBuildLock {
unlock, err := h.BaseFs.LockBuild()
if err != nil {
return fmt.Errorf("failed to acquire a build lock: %w", err)
}
defer unlock()
}
defer func() {
for _, s := range h.Sites {
s.Deps.BuildEndListeners.Notify()
}
}()
errCollector := h.StartErrorCollector()
errs := make(chan error)
go func(from, to chan error) {
var errors []error
i := 0
for e := range from {
i++View on GitHub (pinned to 52c9bd7908)