golangci/golangci-lint · error
failed to init hash salt: %w
Error message
failed to init hash salt: %w
What it means
`initHashSalt` derives a salt from the go.mod hash to key the lint cache. If it fails — e.g. it cannot locate or read go.mod, or cannot compute the hash — the error is wrapped as `failed to init hash salt: %w`. This happens in run's `preRunE`, before any packages are loaded.
Source
Thrown at pkg/commands/run.go:213
c.fileCache = fsutils.NewFileCache()
c.lineCache = fsutils.NewLineCache(c.fileCache)
sw := timeutils.NewStopwatch("pkgcache", c.log.Child(logutils.DebugKeyStopwatch))
pkgCache, err := cache.NewCache(sw, c.log.Child(logutils.DebugKeyPkgCache))
if err != nil {
return fmt.Errorf("failed to build packages cache: %w", err)
}
guard := load.NewGuard()
pkgLoader := lint.NewPackageLoader(c.log.Child(logutils.DebugKeyLoader), c.cfg, args, c.goenv, guard)
c.contextBuilder = lint.NewContextBuilder(c.cfg, pkgLoader, pkgCache, guard)
if err = initHashSalt(c.log.Child(logutils.DebugKeyGoModSalt), c.buildInfo.Version, c.cfg); err != nil {
return fmt.Errorf("failed to init hash salt: %w", err)
}
if ok := c.acquireFileLock(); !ok {
return errors.New("parallel golangci-lint is running")
}
return nil
}
func (c *runCommand) postRun(_ *cobra.Command, _ []string) {
c.releaseFileLock()
}
func (c *runCommand) execute(_ *cobra.Command, _ []string) {
needTrackResources := logutils.IsVerbose() || c.opts.PrintResourcesUsage
trackResourcesEndCh := make(chan struct{})
View on GitHub (pinned to ed7a235d2d)
Solutions
- Run golangci-lint from the module root where go.mod exists (or set the working directory correctly in CI).
- Restore/repair go.mod (`git checkout go.mod`, or `go mod init` if missing).
- Check that go.mod is readable by the current user.
- Read the wrapped error after the message for the precise cause (file not found vs read error).
Example fix
# before (CI step runs from repo root, linter run in subdir)
- run: golangci-lint run ./pkg/...
# after
- run: golangci-lint run ./pkg/... # executed at module root containing go.mod
working-directory: ${{ github.workspace }} Defensive patterns
Strategy: validation
Validate before calling
// confirm go.mod exists and is readable at the working directory
if _, err := os.Stat("go.mod"); err != nil {
return fmt.Errorf("run golangci-lint from a module root: %w", err)
} Try / catch
if err := initHashSalt(log, version, cfg); err != nil {
return fmt.Errorf("failed to init hash salt: %w", err) // usually go.mod missing/unreadable
} Prevention
- Run golangci-lint from the module root containing go.mod.
- Set working-directory correctly in CI jobs running in subdirectories.
- Don't delete or corrupt go.mod; restore it with git checkout if broken.
- Keep go.mod readable by the user executing the linter.
When it happens
Trigger: Running golangci-lint where go.mod cannot be found/read (no module context, go.mod unreadable, or the file is malformed), causing the salt derivation to fail.
Common situations: Running the linter outside a Go module directory; go.mod deleted or corrupted; permission problems on go.mod; running against a GOPATH-style project with no module; symlink/checkout issues in CI leaving go.mod missing.
Related errors
- failed to build packages cache: %w
- failed to read go.mod: %w
- failed to compute go.sum: %w
- failed to gob decode: %w
- failed to remove dir %s: %w
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/2399114f1da91591.
Report an issue: GitHub.