getsops/sops · error
Error marshaling metadata: %s
Error message
Error marshaling metadata: %s
What it means
Emitted by the JSON Store's EmitEncryptedFile when stores.SerializeMetadata fails to convert the tree's sops.Metadata struct into an embeddable tree branch. This indicates the in-memory metadata of the tree could not be serialized (typically a required metadata field conversion failure, not a user data problem).
Source
Thrown at stores/json/store.go:352
// LoadPlainFile loads plaintext json file bytes onto a sops.TreeBranches object
func (store *Store) LoadPlainFile(in []byte) (sops.TreeBranches, error) {
branch, err := store.treeBranchFromJSON(in)
if err != nil {
return nil, fmt.Errorf("Could not unmarshal input data: %s", err)
}
return sops.TreeBranches{
branch,
}, nil
}
// EmitEncryptedFile returns the encrypted bytes of the json file corresponding to a
// sops.Tree runtime object
func (store *Store) EmitEncryptedFile(in sops.Tree) ([]byte, error) {
branches, err := stores.SerializeMetadata(in, stores.MetadataOpts{
Flatten: stores.MetadataFlattenNone,
})
if err != nil {
return nil, fmt.Errorf("Error marshaling metadata: %s", err)
}
return store.EmitPlainFile(branches)
}
// EmitPlainFile returns the plaintext bytes of the json file corresponding to a
// sops.TreeBranches runtime object
func (store *Store) EmitPlainFile(in sops.TreeBranches) ([]byte, error) {
out, err := store.jsonFromTreeBranch(in[0])
if err != nil {
return nil, fmt.Errorf("Error marshaling to json: %s", err)
}
out = append(out, '\n')
return out, nil
}
// EmitValue returns bytes corresponding to a single encoded value
// in a generic interface{} object
func (store *Store) EmitValue(v interface{}) ([]byte, error) {View on GitHub (pinned to 13442bb981)
Solutions
- Build the tree via LoadEncryptedFile/decryption rather than hand-constructing Metadata, so all fields are populated
- Inspect the wrapped error (%s) to identify which metadata field failed to convert
- Verify every required Metadata field is set (MAC, KeyGroups, ShamirThreshold, Version, etc.) in custom code
- Upgrade/downgrade sops to match the metadata version of the file being processed
Example fix
// before
md := sops.Metadata{} // empty metadata
tree.Metadata = md
out, err := store.EmitEncryptedFile(tree) // "Error marshaling metadata"
// after
tree.Metadata.Version = version // populate all required fields, or:
tree, _ = store.LoadEncryptedFile(originalBytes) // derive metadata from a real file Defensive patterns
Strategy: try-catch
Validate before calling
func metadataComplete(md sops.Metadata) bool {
return len(md.KeyGroups) > 0 && md.Version != "" && len(md.MAC) > 0 || md.Version != "" && md.MessageAuthenticationCode != nil
}
// ensure tree.Metadata is populated (from LoadEncryptedFile) before emitting Try / catch
out, err := store.EmitEncryptedFile(tree)
if err != nil {
if strings.HasPrefix(err.Error(), "Error marshaling metadata") {
return fmt.Errorf("tree.Metadata is incomplete/invalid: %w", err)
}
return err
} Prevention
- Derive trees from LoadEncryptedFile rather than constructing Metadata by hand
- Set every required Metadata field (KeyGroups, ShamirThreshold, MAC, Version)
- Keep library and file metadata versions in sync
When it happens
Trigger: Calling EmitEncryptedFile on a sops.Tree whose Metadata field is incomplete or invalid — e.g. a programmatically built tree missing message authentication, key groups, or having a zero-value Metadata that fails metadataFromInternal/serialization.
Common situations: Custom tooling that constructs a sops.Tree by hand (missing Shards/KeyGroups/LastModified), edits to metadata after decryption, or library version changes where metadata fields were added that a hand-built Metadata struct lacks.
Related errors
- Error marshaling metadata: %s
- Error while serializing metadata: %w
- Found duplicate %v entry
- Error while flattening 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/592e02082f5f1fc5.
Report an issue: GitHub.