golangci/golangci-lint · error
can't read viper config: %w
Error message
can't read viper config: %w
What it means
parseConfig calls viper.ReadInConfig; if reading fails for reasons other than "config file not found" (parse errors, permission, IO), the error is wrapped as "can't read viper config" and config loading stops.
Source
Thrown at pkg/config/base_loader.go:168
searchPaths = append(searchPaths, home)
}
return searchPaths
}
func (l *BaseLoader) parseConfig() error {
if err := l.viper.ReadInConfig(); err != nil {
if _, ok := errors.AsType[viper.ConfigFileNotFoundError](err); ok {
// Load configuration from flags only.
err = l.viper.Unmarshal(l.cfg, customDecoderHook())
if err != nil {
return fmt.Errorf("can't unmarshal config by viper (flags): %w", err)
}
return nil
}
return fmt.Errorf("can't read viper config: %w", err)
}
err := l.setConfigDir()
if err != nil {
return err
}
// Load configuration from all sources (flags, file).
if err := l.viper.Unmarshal(l.cfg, customDecoderHook()); err != nil {
return fmt.Errorf("can't unmarshal config by viper (flags, file): %w", err)
}
if l.cfg.IsInternalTest() { // just for testing purposes: to detect config file usage
_, _ = fmt.Fprintln(logutils.StdOut, "test")
os.Exit(exitcodes.Success)
}
return nilView on GitHub (pinned to ed7a235d2d)
Solutions
- Validate the YAML/JSON config file syntax (yamllint or a YAML parser) and fix syntax errors
- Check file permissions so the lint process can read the config file
- Use `golangci-lint config path` to see which config file is being picked up; remove or fix stale ones
- Read the wrapped %w error — viper reports the file and line of parse failures
Example fix
# before (invalid YAML)
issues:
exclude-dirs:
- vendor
# after
issues:
exclude-dirs:
- vendor Defensive patterns
Strategy: validation
Validate before calling
func validYAML(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return err
}
var v map[string]any
return yaml.Unmarshal(data, &v)
}
// run in CI before golangci-lint: validYAML(".golangci.yml") Prevention
- Lint your config YAML in CI (yamllint) before running golangci-lint
- Watch for tabs — YAML forbids them for indentation
- Clean merge-conflict markers before linting
- Check `golangci-lint config path` to know which config file is loaded
When it happens
Trigger: A config file exists at the resolved location but viper cannot read/parse it: malformed YAML/JSON/TOML syntax, unreadable file permissions, unreadable config directory (setConfigDir side effects happen after), or a corrupted search path.
Common situations: Hand-edited .golangci.yml with indentation/tab mistakes; merge-conflict markers left in the file; root-owned config in CI containers; a stray .golangci.yaml in a parent directory with bad syntax.
Related errors
- failed to calculate config salt: %w
- failed to JSON marshal config linter settings: %w
- can't unmarshal config by viper (flags): %w
- can't unmarshal config by viper (flags, file): %w
- the configuration contains invalid elements
AI-assisted analysis of golangci/golangci-lint@ed7a235d2d (2026-09-02).
Data as JSON: /api/errors/6eb81fa21dafa7c6.
Report an issue: GitHub.