gohugoio/hugo · error

failed to calculate hash: %w

Error message

failed to calculate hash: %w

What it means

Wrapped error from `resourceHash.init` (resource.go:679-682) when `hashImage` fails to compute xxhash from the open reader. `hashImage` delegates to `hashing.XXHashFromReader`; failure means the reader returned an error mid-read (truncated file, network-blip on remote reader, mid-read disk failure). Distinct from 586: source opened but bytes could not be hashed.

Source

Thrown at resources/resource.go:681

	value    uint64
	size     int64
	initOnce sync.Once
}

func (r *resourceHash) init(l hugio.ReadSeekCloserProvider) error {
	var initErr error
	r.initOnce.Do(func() {
		var hash uint64
		var size int64
		f, err := l.ReadSeekCloser()
		if err != nil {
			initErr = fmt.Errorf("failed to open source: %w", err)
			return
		}
		defer f.Close()
		hash, size, err = hashImage(f)
		if err != nil {
			initErr = fmt.Errorf("failed to calculate hash: %w", err)
			return
		}
		r.value = hash
		r.size = size
	})

	return initErr
}

func hashImage(r io.ReadSeeker) (uint64, int64, error) {
	return hashing.XXHashFromReader(r)
}

// InternalResourceTargetPath is used internally to get the target path for a Resource.
func InternalResourceTargetPath(r resource.Resource) string {
	return r.(targetPathProvider).targetPath()
}

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Re-fetch or restore the source asset so it is complete and stable during the build.
  2. Run the build with no concurrent writers touching `assets/`/`resources/`/`static/`.
  3. For remote resources, raise `timeout` and confirm the server returns full Content-Length.
  4. Run `hugo --gc` to evict any half-written cached resource.
  5. Check dmesg / disk health if read errors recur on local files.
Defensive patterns

Strategy: retry

Try / catch

// Retry hash on transient read errors.
var res resource.Resource
var err error
for i := 0; i < 3; i++ {
	res, err = rs.NewResource(...)
	if err == nil || !strings.Contains(err.Error(), "failed to calculate hash") {
		break
	}
	time.Sleep(time.Duration(i+1) * time.Second)
}

Prevention

When it happens

Trigger: Source opens successfully but errors during the actual read inside `XXHashFromReader` -- partial download, file truncated by another writer, read timeout on a remote-backed reader, disk I/O error mid-stream.

Common situations: File being written concurrently while Hugo hashes it (asset pipeline mid-build); NFS/SMB hiccup mid-read; remote resource partial fetch where the reader yields EOF early or returns an error after some bytes; corrupted file on disk.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/c5d092d4972cb9a9. Report an issue: GitHub.