getsops/sops · error
Found duplicate %v entry
Error message
Found duplicate %v entry
What it means
Raised by ExtractMetadata when the sops tree contains more than one `sops` metadata entry in the first branch. The parser expects exactly one nested `sops` mapping holding the encrypted-file metadata; a second one is ambiguous and treated as corruption.
Source
Thrown at stores/metadata.go:116
if err != nil {
return md, err
}
err = d.Decode(m)
return md, err
}
// 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]View on GitHub (pinned to 13442bb981)
Solutions
- Open the file and remove the duplicate `sops` metadata block, keeping exactly one
- Restore the file from git (git checkout -- file) or from backup if a merge corrupted it
- Re-encrypt a known-good plaintext with sops instead of hand-repairing metadata
- Validate the file structure with a JSON/YAML parser to spot duplicated top-level keys
Example fix
// before (file contains two sops blocks after a bad merge)
{"data": "ENC[AES256_GCM,...]", "sops": {...}, "sops": {...}}
// after: keep exactly one sops metadata block
{"data": "ENC[AES256_GCM,...]", "sops": {"mac": "...", "pgp": [...]}} Defensive patterns
Strategy: validation
Validate before calling
func countSopsKeys(b []byte) (int, error) {
var m map[string]json.RawMessage
if err := json.Unmarshal(b, &m); err != nil {
return 0, err
}
return len(m["sops"]), nil // >1 means duplicate risk in raw text; check raw text for key duplication
}
// for raw text: count occurrences of the top-level sops key before loading
count := strings.Count(string(data), `"sops": {`) Try / catch
tree, err := store.LoadEncryptedFile(data)
if err != nil {
if strings.Contains(err.Error(), "Found duplicate sops entry") {
return fmt.Errorf("file has more than one sops metadata block; resolve merge conflict or restore from git: %w", err)
}
return err
} Prevention
- Never hand-edit the sops metadata block in encrypted files
- Resolve git merge conflicts in encrypted files with a sops-aware merge driver or by re-encrypting from plaintext
- Don't concatenate or append sops output to existing encrypted files
When it happens
Trigger: Calling LoadEncryptedFile (which calls ExtractMetadata) on a file that literally contains two `sops:` metadata blocks — e.g. from a merge conflict, a concatenation of two encrypted files, a bad re-encryption, or a user manually editing the file and duplicating the sops block.
Common situations: Git merge conflicts in encrypted files resolved incorrectly, scripts that append sops output to existing files, YAML/JSON files edited by hand where the sops key was re-added, or file corruption from interrupted writes.
Related errors
- Error marshaling metadata: %s
- Error marshaling metadata: %s
- Found %v entry that is not a mapping
- Error while serializing metadata: %w
- Found key %q in encrypted data, which starts with the reserv
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/1cc624624f2b6b73.
Report an issue: GitHub.