getsops/sops · error
Found key %q in encrypted data, which starts with the reserv
Error message
Found key %q in encrypted data, which starts with the reserved key prefix %q for SOPS metadata
What it means
Raised by SerializeMetadata when user data contains a key that begins with the reserved `sops_` prefix while MetadataFlattenFull is active (flat metadata shares the same namespace as data keys). Emitting such a file would make metadata keys indistinguishable from data keys, so sops refuses.
Source
Thrown at stores/metadata.go:309
}
}
}
if opts.Flatten != MetadataFlattenFull {
md = sops.TreeBranch{
sops.TreeItem{
Key: SopsMetadataKey,
Value: md,
},
}
}
var result sops.TreeBranches
for _, branch := range data.Branches {
newBranch := make(sops.TreeBranch, 0, len(branch)+len(md))
for _, item := range branch {
if key, ok := item.Key.(string); ok {
if opts.Flatten == MetadataFlattenFull {
if strings.HasPrefix(key, SopsPrefix) {
return nil, fmt.Errorf("Found key %q in encrypted data, which starts with the reserved key prefix %q for SOPS metadata", key, SopsPrefix)
}
} else {
if key == SopsMetadataKey {
return nil, fmt.Errorf("Found key %q in encrypted data, which is a reserved key used for SOPS metadata", key)
}
}
}
newBranch = append(newBranch, item)
}
for _, item := range md {
newBranch = append(newBranch, item)
}
result = append(result, newBranch)
}
return result, nil
}
View on GitHub (pinned to 13442bb981)
Solutions
- Rename the data key so it does not start with `sops_` (or `SOPS_` in env files)
- Store the value under a different name, e.g. `cfg_sops_settings` instead of `sops_settings`
- If the key must keep its name, use a format that stores metadata in a nested `sops` mapping (json/yaml stores) instead of flattening
- Filter out reserved-prefix keys before encrypting if they are not needed in the encrypted output
Example fix
// before: env file SOPS_CONFIG_URL=https://example.com // after: avoid reserved sops_ prefix in flattened stores MYAPP_SOPS_CONFIG_URL=https://example.com
Defensive patterns
Strategy: validation
Validate before calling
func hasReservedKeys(tree sops.Tree, prefix string) []string {
var bad []string
for _, branch := range tree.Branches {
for _, item := range branch {
if k, ok := item.Key.(string); ok && strings.HasPrefix(k, prefix) {
bad = append(bad, k)
}
}
}
return bad
}
if bad := hasReservedKeys(tree, "sops_"); len(bad) > 0 {
return fmt.Errorf("rename reserved-prefixed keys before encrypting: %v", bad)
} Type guard
func isReservedKey(k interface{}, prefix string) bool {
s, ok := k.(string)
return ok && strings.HasPrefix(s, prefix)
} Try / catch
out, err := stores.SerializeMetadata(tree, opts)
if err != nil {
if strings.Contains(err.Error(), "reserved key prefix") {
return fmt.Errorf("rename keys starting with sops_ before encrypting with flattened metadata: %w", err)
}
return err
} Prevention
- Never name data keys/env vars with the sops_ (SOPS_) prefix in flattened stores
- Use json/yaml stores (nested sops metadata) if such key names are unavoidable
- Scan input files for reserved prefixes before encryption
- Document key-naming rules for teams generating env files consumed by sops
When it happens
Trigger: Calling SerializeMetadata (or EmitEncryptedFile with an env/dotenv store) on a tree whose branches contain a string key starting with `sops_`, e.g. `sops_config`, `sops_env_var`, when Flatten is MetadataFlattenFull.
Common situations: Env/dotenv files containing variables literally named `SOPS_...` (common in CI configs referencing SOPS_* environment variables) being encrypted with the env store, or scripts generating keys prefixed with sops_.
Related errors
- Error marshaling metadata: %s
- Error marshaling metadata: %s
- Found duplicate %v entry
- Error while serializing metadata: %w
- Unknown datatype: %s
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/d19b73fb38421747.
Report an issue: GitHub.