getsops/sops · error

error loading config: no matching creation rules found

Error message

error loading config: no matching creation rules found

What it means

After iterating all creation_rules and compiling their path_regexes, sops builds a Config only when a rule matched the file path. If no rule matched (rule == nil), the config cannot be resolved and sops fails with this message. This is the config file's way of saying 'this file is not covered by any creation rule'.

Source

Thrown at config/config.go:602

	var rule *creationRule

	for _, r := range conf.CreationRules {
		if r.PathRegex == "" {
			rule = &r
			break
		}
		reg, err := regexp.Compile(r.PathRegex)
		if err != nil {
			return nil, fmt.Errorf("can not compile regexp: %w", err)
		}
		if reg.MatchString(filePath) {
			rule = &r
			break
		}
	}

	if rule == nil {
		return nil, fmt.Errorf("error loading config: no matching creation rules found")
	}

	config, err := configFromRule(rule, kmsEncryptionContext)
	if err != nil {
		return nil, err
	}

	return config, nil
}

// LoadCreationRuleForFile load the configuration for a given SOPS file from the config file at confPath. A kmsEncryptionContext
// should be provided for configurations that do not contain key groups, as there's no way to specify context inside
// a SOPS config file outside of key groups.
func LoadCreationRuleForFile(confPath string, filePath string, kmsEncryptionContext map[string]*string) (*Config, error) {
	conf, err := loadConfigFile(confPath)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 13442bb981)

Solutions

  1. Add or fix a creation rule's path_regex to match the file path you pass to sops (print the exact path with pwd)
  2. Run sops from the directory containing .sops.yaml so relative matching behaves as authored
  3. Add a default catch-all rule at the end of creation_rules (path_regex: '.*' with a key group) for uncovered files
  4. Confirm the file extension type is included, e.g. add '.*\.(env|yaml|yml|json)'

Example fix

# before
creation_rules:
  - path_regex: 'secrets/.*\.yaml$'
    kms: 'arn:aws:kms:...'
# after
creation_rules:
  - path_regex: 'secrets/.*\.yaml$'
    kms: 'arn:aws:kms:...'
  - path_regex: '.*'
    kms: 'arn:aws:kms:...'
Defensive patterns

Strategy: validation

Validate before calling

var matched bool
for _, r := range cfg.CreationRules {
    if re, err := regexp.Compile(r.PathRegex); err == nil && re.MatchString(filePath) {
        matched = true
        break
    }
}
if !matched {
    return fmt.Errorf("no creation rule in %s matches %s", confPath, filePath)
}

Try / catch

cfg, err := createConfigForFile(path, confPath, nil)
if err != nil && strings.Contains(err.Error(), "no matching creation rules") {
    return fmt.Errorf("add a creation rule matching %s in %s", path, confPath)
}

Prevention

When it happens

Trigger: Encrypting a file whose path does not match any creation_rules entry's path_regex, running sops in a directory where the .sops.yaml rules use paths relative to a different root, or the config has an empty creation_rules list.

Common situations: Monorepo subdirectory run where .sops.yaml sits at the root and the regex assumes root-relative paths; renaming directories without updating path_regex; missing catch-all rule for new file types.

Related errors


AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01). Data as JSON: /api/errors/55cfd449f8d62aad. Report an issue: GitHub.