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

  1. Read the wrapped error after the colon to find the exact field and bad element type
  2. Fix the offending key list in .sops.yaml so every entry is a plain string
  3. 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

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


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