getsops/sops · error
Found %v entry that is not a mapping
Error message
Found %v entry that is not a mapping
What it means
Raised by ExtractMetadata when a `sops` key is found in the first branch but its value is not a nested mapping (sops.TreeBranch). The metadata block must be an object/map; a scalar or array value under the `sops` key cannot hold the metadata fields.
Source
Thrown at stores/metadata.go:122
// ExtractMetadata extracts SOPS metadata from the supplied tree branches.
func ExtractMetadata(branches sops.TreeBranches, opts MetadataOpts) (sops.TreeBranches, sops.Metadata, error) {
var metadataTree sops.TreeBranch
if opts.Flatten != MetadataFlattenFull {
first := true
for bi, branch := range branches {
i := 0
for i < len(branch) {
if branch[i].Key == SopsMetadataKey {
if bi == 0 {
if !first {
return nil, sops.Metadata{}, fmt.Errorf("Found duplicate %v entry", SopsMetadataKey)
}
first = false
if tree, ok := branch[i].Value.(sops.TreeBranch); ok {
metadataTree = tree
} else {
return nil, sops.Metadata{}, fmt.Errorf("Found %v entry that is not a mapping", SopsMetadataKey)
}
}
branch = append(branch[:i], branch[i+1:]...)
} else {
i++
}
}
branches[bi] = branch
}
} else {
if len(branches) >= 1 {
branch := branches[0]
for i := 0; i < len(branch); i++ {
if key, ok := branch[i].Key.(string); ok {
if strings.HasPrefix(key, SopsPrefix) {
entry := branch[i]
entry.Key = key[len(SopsPrefix):]
metadataTree = append(metadataTree, entry)View on GitHub (pinned to 13442bb981)
Solutions
- Rename the conflicting data key (anything other than `sops`) and re-encrypt
- If the file is meant to be encrypted, re-create it with `sops -e` so a proper sops metadata mapping is embedded
- If the file is plaintext, don't pass it to LoadEncryptedFile/decryption paths
- Restore the original metadata object if the file was edited by hand
Example fix
// before: key 'sops' used for data
{"sops": "ENC[AES256_GCM,...]"}
// after: rename data key; 'sops' is reserved for metadata
{"my_sops_config": "ENC[AES256_GCM,...]", "sops": {"mac": "...", ...}} Defensive patterns
Strategy: validation
Validate before calling
var probe struct {
Sops json.RawMessage `json:"sops"`
}
if err := json.Unmarshal(data, &probe); err == nil && len(probe.Sops) > 0 {
var obj map[string]interface{}
if err := json.Unmarshal(probe.Sops, &obj); err != nil || obj == nil {
return errors.New(`"sops" key is present but not a JSON object`)
}
} Type guard
func isTreeBranch(v interface{}) bool {
_, ok := v.(sops.TreeBranch)
return ok
} Try / catch
tree, err := store.LoadEncryptedFile(data)
if err != nil {
if strings.Contains(err.Error(), "entry that is not a mapping") {
return fmt.Errorf(`the "sops" key must hold a metadata object: %w`, err)
}
return err
} Prevention
- Never use `sops` as a data key name in files you intend to encrypt
- Create encrypted files only via `sops -e`, never by hand-adding a sops key
- Only pass previously encrypted files to decryption/LoadEncryptedFile paths
When it happens
Trigger: Calling LoadEncryptedFile on a file where the `sops` key maps to a non-object value — e.g. `sops: ENC[...]`, `sops: true`, `sops: [1,2]` — typically from a data key legitimately named `sops` holding encrypted data instead of metadata, or a hand-mangled file.
Common situations: A user's real data uses the key `sops` and they created the file without proper metadata (unencrypted copy that includes a data key literally named sops), manual edits that replaced the metadata object, or a format-mismatch where a plain data file is fed through an encrypted-file loader.
Related errors
- Found duplicate %v entry
- Error marshaling metadata: %s
- Error marshaling metadata: %s
- Internal error: unexpected metadata conversion result %T
- Error while serializing metadata: %w
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/83fc5a3318d6c1d2.
Report an issue: GitHub.