getsops/sops · error
invalid %s key configuration: %w
Error message
invalid %s key configuration: %w
What it means
getKeysWithValidation wraps errors from the per-key-type getters (GetKMSKeys, GetAgeKeys, etc.) with a message naming the key type, so failures like parseKeyField type errors surface as `invalid age key configuration: ...`. It is a contextual wrapper — the root cause is in the wrapped error.
Source
Thrown at config/config.go:366
keyGroup = append(keyGroup, key)
} else {
return nil, err
}
}
for _, k := range group.Vault {
if masterKey, err := hcvault.NewMasterKeyFromURI(k); err == nil {
keyGroup = append(keyGroup, masterKey)
} else {
return nil, err
}
}
return deduplicateKeygroup(keyGroup), nil
}
func getKeysWithValidation(getKeysFunc func() ([]string, error), keyType string) ([]string, error) {
keys, err := getKeysFunc()
if err != nil {
return nil, fmt.Errorf("invalid %s key configuration: %w", keyType, err)
}
return keys, nil
}
func getKeyGroupsFromCreationRule(cRule *creationRule, kmsEncryptionContext map[string]*string) ([]sops.KeyGroup, error) {
var groups []sops.KeyGroup
if len(cRule.KeyGroups) > 0 {
for _, group := range cRule.KeyGroups {
keyGroup, err := extractMasterKeys(group)
if err != nil {
return nil, err
}
groups = append(groups, keyGroup)
}
} else {
var keyGroup sops.KeyGroup
ageKeys, err := getKeysWithValidation(cRule.GetAgeKeys, "age")
if err != nil {View on GitHub (pinned to 13442bb981)
Solutions
- Read the wrapped error after the colon to find the exact field and bad element type
- Fix the offending key list in .sops.yaml so every entry is a plain string
- Keep key entries under creation_rules as strings, or move multi-key setups into key_groups
Example fix
# before
creation_rules:
- path_regex: .*\n age:
- {recipient: age1abc} # invalid -> 'invalid age key configuration'
# after
creation_rules:
- path_regex: .*
age:
- "age1abc..." Defensive patterns
Strategy: validation
Validate before calling
// pre-validate creation rule key fields before building key groups
for _, rule := range cfg.CreationRules {
for _, k := range rule.Age {
if _, ok := k.(string); !ok {
return fmt.Errorf("age entries must be plain strings in creation rule %q", rule.PathRegex)
}
}
} Try / catch
groups, err := config.GetKeyGroups(...) // or the code path using getKeysWithValidation
if err != nil {
var prefix string
if _, conv := fmt.Sscanf(err.Error(), "invalid %s key configuration", &prefix); conv == nil {
return fmt.Errorf("bad key list for %s in .sops.yaml; see wrapped cause", prefix)
}
return err
} Prevention
- Read the wrapped cause after 'invalid <type> key configuration:' to find the real problem
- Keep all key entries in creation_rules as plain quoted strings
- Test encryption with `sops -e /dev/null` after editing .sops.yaml
- Maintain a golden/example .sops.yaml in the repo as the canonical shape
When it happens
Trigger: Calling getKeyGroupsFromCreationRule / config resolution for a creation rule where the underlying getter (e.g. GetAgeKeys) returns an error such as a non-string entry in the key list (error 66/67).
Common situations: A creation_rules entry in .sops.yaml has a malformed key list (maps instead of strings), so building key groups during `sops -e` fails with this prefixed error.
Related errors
- invalid %s key configuration: expected string in list, got %
- invalid %s key configuration: expected string, []string, or
- Could not unmarshal config file: %s
- config file not found
- error loading config: %s
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/9e10fc3c77e6c42b.
Report an issue: GitHub.