getsops/sops · error
Value to encrypt has unsupported type %T
Error message
Value to encrypt has unsupported type %T
What it means
Encrypt supports a fixed set of plaintext Go types (string, int/float, bool, time.Time, sops.Comment). Any other Go type reaches the default branch of the type switch and is rejected with this error naming the actual %T type. It protects the format: unencodable values would silently corrupt the document.
Source
Thrown at aes/cipher.go:194
case bool:
encryptedType = "bool"
// The Python version encodes booleans with Titlecase
if value {
plainBytes = []byte("True")
} else {
plainBytes = []byte("False")
}
case time.Time:
encryptedType = "time"
plainBytes, err = value.MarshalText()
if err != nil {
return "", fmt.Errorf("Error marshaling timestamp %q: %w", value, err)
}
case sops.Comment:
encryptedType = "comment"
plainBytes = []byte(value.Value)
default:
return "", fmt.Errorf("Value to encrypt has unsupported type %T", value)
}
out := gcm.Seal(nil, iv, plainBytes, []byte(additionalData))
return fmt.Sprintf("ENC[AES256_GCM,data:%s,iv:%s,tag:%s,type:%s]",
base64.StdEncoding.EncodeToString(out[:len(out)-cryptoaes.BlockSize]),
base64.StdEncoding.EncodeToString(iv),
base64.StdEncoding.EncodeToString(out[len(out)-cryptoaes.BlockSize:]),
encryptedType), nil
}
View on GitHub (pinned to 13442bb981)
Solutions
- Convert the value to a scalar (string, int, float, bool, time.Time) before encrypting.
- For complex values, serialize to a string (YAML/JSON) and encrypt the string.
- Add a case to the type switch in Encrypt if you fork and need a new supported type.
Example fix
// before
cipher.Encrypt(map[string]interface{}{"a": 1}, key, ad)
// after
cipher.Encrypt(fmt.Sprintf("a: 1", ), key, ad) // or encrypt a scalar only Defensive patterns
Strategy: type-guard
Validate before calling
func encodable(v interface{}) bool {
switch v.(type) {
case string, int, int64, float64, bool, time.Time, sops.Comment:
return true
}
return false
} Type guard
if !encodable(value) {
value = fmt.Sprintf("%v", value) // coerce to string first
} Try / catch
ciphertext, err := cipher.Encrypt(v, key, ad)
if err != nil && strings.Contains(err.Error(), "unsupported type") {
return cipher.Encrypt(fmt.Sprintf("%v", v), key, ad)
} Prevention
- Insert only leaf scalars into sops TreeBranches
- Serialize nested structures to YAML/JSON strings before encrypting
- Add unit tests asserting tree values are encodable types
When it happens
Trigger: Passing a value of an unsupported type to Cipher.Encrypt — e.g. a map, slice, nil pointer, or custom struct inserted into a sops TreeBranch instead of a scalar.
Common situations: Programmatic use of the sops API where developers insert arbitrary Go objects into the tree; reflection-based tooling that forwards raw parsed YAML/JSON nodes (maps/slices) instead of leaves.
Related errors
- Unknown datatype: %s
- Could not initialize AES GCM encryption cipher: %s
- Could not generate random bytes for IV: %s
- Could not create GCM: %s
- Error marshaling timestamp %q: %w
AI-assisted analysis of getsops/sops@13442bb981 (2026-09-01).
Data as JSON: /api/errors/20e78874b305748e.
Report an issue: GitHub.