gohugoio/hugo · error

failed to acquire a build lock: %w

Error message

failed to acquire a build lock: %w

What it means

Before building, Hugo takes a file-based lock (via BaseFs.LockBuild) to prevent two Hugo processes from writing the same destination concurrently. This error means acquiring that lock file (.hugo_build.lock in the project root) failed — either another process holds it past the timeout or the lock file can't be created.

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 8a468df065)

Solutions

  1. Stop the other Hugo process using the same project (commonly a running `hugo server`).
  2. Delete a stale `.hugo_build.lock` in the project root if no other process is running.
  3. Ensure the project directory is writable by the build user.
  4. If concurrent builds are intentional and write to different destinations, pass `--noBuildLock`.
Defensive patterns

Strategy: retry

Validate before calling

// ensure only one build runs per HugoSites instance
// serialize callers: guard Build() with your own queue if invoking concurrently

Try / catch

err := h.Build(cfg)
if err != nil && strings.Contains(err.Error(), "failed to acquire a build lock") {
    // another build in flight; wait and retry once
    time.Sleep(500 * time.Millisecond)
    err = h.Build(cfg)
}

Prevention

When it happens

Trigger: HugoSites.Build with config.NoBuildLock=false when another hugo build/server against the same source is running and holds .hugo_build.lock, when a crashed process left a stale lock, or when the project directory is read-only so the lock file cannot be created.

Common situations: Running `hugo` while `hugo server` is still up in another terminal; CI jobs building the same checkout in parallel; read-only mounted source directories in containers; stale .hugo_build.lock after an OOM-killed build.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/cdd888c605a1807c.json. Report an issue: GitHub ↗.