getsops/sops · error
could not read config file: %s
Error message
could not read config file: %s
What it means
loadConfigFile wraps any error returned by os.ReadFile when the sops config file cannot be read from disk. This is a pre-parse failure: the file is missing, unreadable, or the path is a directory. sops aborts config loading because no rules can be evaluated without the file contents.
Source
Thrown at config/config.go:456
if err != nil {
return nil, err
}
vaultKeys, err := hcvault.NewMasterKeysFromURIs(strings.Join(vaultKeyUris, ","))
if err != nil {
return nil, err
}
for _, k := range vaultKeys {
keyGroup = append(keyGroup, k)
}
groups = append(groups, keyGroup)
}
return groups, nil
}
func loadConfigFile(confPath string) (*configFile, error) {
confBytes, err := os.ReadFile(confPath)
if err != nil {
return nil, fmt.Errorf("could not read config file: %s", err)
}
conf := &configFile{}
conf.Stores = *NewStoresConfig()
err = conf.load(confBytes)
if err != nil {
return nil, fmt.Errorf("error loading config: %s", err)
}
return conf, nil
}
func configFromRule(rule *creationRule, kmsEncryptionContext map[string]*string) (*Config, error) {
cryptRuleCount := 0
if rule.UnencryptedSuffix != "" {
cryptRuleCount++
}
if rule.EncryptedSuffix != "" {
cryptRuleCount++
}View on GitHub (pinned to 13442bb981)
Solutions
- Verify the config path exists and is a regular file before running sops: ls -la <path>
- Run sops from the directory containing .sops.yaml (or use --config with an absolute path)
- Fix file permissions so the invoking user can read the file (chmod/chown)
- If no config is needed, remove the --config flag or ensure creation rules are passed another way
Example fix
// before sops --config ./conf/sops.yaml encrypt file.yaml // after sops --config $(pwd)/.sops.yaml encrypt file.yaml # path exists and is absolute
Defensive patterns
Strategy: validation
Validate before calling
info, err := os.Stat(confPath)
if err != nil {
return fmt.Errorf("config not accessible at %s: %w", confPath, err)
}
if info.IsDir() {
return fmt.Errorf("%s is a directory, not a config file", confPath)
} Try / catch
groups, err := loadConfigFile(confPath)
if err != nil {
var perr *fs.PathError
if errors.As(err, &perr) && os.IsNotExist(perr) {
// fall back to defaults or create a template config
}
return err
} Prevention
- Always resolve the config path with filepath.Abs and stat it before invoking sops
- Ensure .sops.yaml is committed to the repo so CI checkouts include it
- Use --config with an explicit absolute path in scripts
- Add a preflight check in CI that the expected config files exist
When it happens
Trigger: Calling sops with a --config path that does not exist, the default .sops.yaml is absent in a repo where config loading is attempted, or the process lacks read permission on the file.
Common situations: Running sops from a different working directory than the repo root; CI checkouts missing dotfiles; typo in --config flag; file permissions restricted by umask or CI user.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- error loading config: %s
- error loading config: cannot use more than one of encrypted_
- error loading config: no matching destination found in confi
- error loading config: more than one destinations were found
- can not compile regexp: %w
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/2ac76064cdb9f8cc.
Report an issue: GitHub.