{"record":{"id":"890023efa1603e2f","repo":"getsops/sops","slug":"could-not-initialize-aes-gcm-encryption-cipher-s","errorCode":null,"errorMessage":"Could not initialize AES GCM encryption cipher: %s","messagePattern":"Could not initialize AES GCM encryption cipher: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"aes/cipher.go","lineNumber":147,"sourceCode":"\tcase string:\n\t\treturn value == \"\"\n\tcase []byte:\n\t\treturn len(value) == 0\n\tcase sops.Comment:\n\t\treturn isEmpty(value.Value)\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// Encrypt takes one of (string, int, float, bool) and encrypts it with the provided key and additional auth data, returning a sops-format encrypted string.\nfunc (c Cipher) Encrypt(plaintext interface{}, key []byte, additionalData string) (ciphertext string, err error) {\n\tif isEmpty(plaintext) {\n\t\treturn \"\", nil\n\t}\n\taescipher, err := cryptoaes.NewCipher(key)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Could not initialize AES GCM encryption cipher: %s\", err)\n\t}\n\tvar iv []byte\n\tif stash, ok := c.stash[stashKey{plaintext: plaintext, additionalData: additionalData}]; !ok {\n\t\tiv = make([]byte, nonceSize)\n\t\t_, err = rand.Read(iv)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"Could not generate random bytes for IV: %s\", err)\n\t\t}\n\t} else {\n\t\tiv = stash\n\t}\n\tgcm, err := cipher.NewGCMWithNonceSize(aescipher, nonceSize)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"Could not create GCM: %s\", err)\n\t}\n\tvar plainBytes []byte\n\tvar encryptedType string\n\tswitch value := plaintext.(type) {","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/aes/cipher.go#L129-L165","documentation":"Encrypt first builds the underlying AES block cipher from the provided key via cryptoaes.NewCipher. If the key bytes are not a valid AES key length (16, 24, or 32 bytes), NewCipher fails and this error wraps the stdlib message. It indicates the supplied data key is malformed, not a problem with the plaintext.","triggerScenarios":"Calling Cipher.Encrypt with a key slice whose length is not 16/24/32 bytes — e.g. a truncated or wrongly decoded master key, a key master plugin that returned nil/partial bytes, or a raw passphrase passed instead of a derived 32-byte key.","commonSituations":"Misconfigured KMS/HashiCorp Vault key that yields a zero-length data key; base64 data key decoded with the wrong encoding; corrupted local keyring producing short keys.","solutions":["Verify the decrypted data key is exactly 32 bytes (AES-256) before calling Encrypt; log its length.","Fix the key source: re-create/re-encrypt the sops data key with the correct master keys.","Check that the key material is properly decoded (base64/hex) and not truncated or padded incorrectly."],"exampleFix":"// before\nkey := []byte(sharedKey)\ncipher.Encrypt(value, key, ad)\n// after\nif len(sharedKey) != 32 {\n    return fmt.Errorf(\"data key must be 32 bytes, got %d\", len(sharedKey))\n}\ncipher.Encrypt(value, sharedKey, ad)","handlingStrategy":"validation","validationCode":"if len(key) != 16 && len(key) != 24 && len(key) != 32 {\n    return fmt.Errorf(\"AES key must be 16/24/32 bytes, got %d\", len(key))\n}","typeGuard":null,"tryCatchPattern":"ciphertext, err := cipher.Encrypt(v, key, ad)\nif err != nil && strings.Contains(err.Error(), \"Could not initialize AES GCM\") {\n    // re-fetch the data key from the KMS before retrying\n}","preventionTips":["Assert data-key length right after KMS decryption","Use sops's own key service to derive keys rather than manual decoding","Log key length (never the key) when debugging"],"tags":["sops","aes","encryption","invalid-key-length"],"backgroundTag":"invalid-key-length","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}