gohugoio/hugo · error

failed to acquire a build lock: %s

Error message

failed to acquire a build lock: %s

What it means

Before creating new content, Hugo takes the project's build lock (a .hugo_build.lock file) via h.BaseFs.LockBuild() so `hugo new` doesn't race a concurrently running build/server. This error means acquiring that file lock failed — the wrapped error explains why (timeout waiting on another holder, or a filesystem error creating the lock file).

Source

Thrown at create/content.go:87

		sourceFs:    h.PathSpec.Fs.Source,
		ps:          h.PathSpec,
		h:           h,
		cf:          cf,

		kind:       kind,
		targetPath: targetPath,
		force:      force,
	}

	ext := paths.Ext(targetPath)

	b.setArcheTypeFilenameToUse(ext)

	withBuildLock := func() (string, error) {
		if !h.Configs.Base.NoBuildLock {
			unlock, err := h.BaseFs.LockBuild()
			if err != nil {
				return "", fmt.Errorf("failed to acquire a build lock: %s", err)
			}
			defer unlock()
		}

		if b.isDir {
			return "", b.buildDir()
		}

		if ext == "" {
			return "", fmt.Errorf("failed to resolve %q to an archetype template", targetPath)
		}

		if !h.Conf.ContentTypes().IsContentFile(b.targetPath) {
			return "", fmt.Errorf("target path %q is not a known content format", b.targetPath)
		}

		return b.buildFile()
	}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Stop or wait for the other Hugo process (usually `hugo server` or a running build), then retry.
  2. Check the project directory is writable and delete a stale .hugo_build.lock if no Hugo process is running.
  3. On filesystems with broken locking, set `noBuildLock: true` in config or pass `--noBuildLock` (accepting the concurrency risk).
  4. Inspect the wrapped error text for the concrete OS-level cause (permissions, timeout).

Example fix

# before: `hugo new content posts/x.md` fails while `hugo server` is running a long build

# after: stop the server, or if the lock is stale:
rm .hugo_build.lock
hugo new content posts/x.md
Defensive patterns

Strategy: retry

Try / catch

for i := 0; i < 3; i++ {
    err = create.NewContent(h, kind, path, force)
    if err == nil || !strings.Contains(err.Error(), "build lock") { break }
    time.Sleep(time.Second << i)
}

Prevention

When it happens

Trigger: `hugo new content ...` while another Hugo process (e.g. `hugo server`) holds the lock long enough to time out; the lock file or project directory not writable; a stale lock on a filesystem where flock semantics are broken (some network mounts). Skipped entirely when `noBuildLock: true` is configured.

Common situations: Running `hugo new` while a long build is in progress; read-only project checkouts or CI workspaces; Docker/NFS/network volumes with unreliable file locking; leftover .hugo_build.lock after a crash on such filesystems.

Related errors


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