{"record":{"id":"57f667e896843616","repo":"hashicorp/terraform","slug":"invalid-private-key-s","errorCode":null,"errorMessage":"invalid private key: %s","messagePattern":"invalid private key: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/lang/funcs/crypto.go","lineNumber":187,"sourceCode":"\t\tkey := args[1].AsString()\n\n\t\tb, err := base64.StdEncoding.DecodeString(s)\n\t\tif err != nil {\n\t\t\treturn cty.UnknownVal(cty.String), function.NewArgErrorf(0, \"failed to decode input %q: cipher text must be base64-encoded\", s)\n\t\t}\n\n\t\trawKey, err := ssh.ParseRawPrivateKey([]byte(key))\n\t\tif err != nil {\n\t\t\tvar errStr string\n\t\t\tswitch e := err.(type) {\n\t\t\tcase asn1.SyntaxError:\n\t\t\t\terrStr = strings.ReplaceAll(e.Error(), \"asn1: syntax error\", \"invalid ASN1 data in the given private key\")\n\t\t\tcase asn1.StructuralError:\n\t\t\t\terrStr = strings.ReplaceAll(e.Error(), \"asn1: struture error\", \"invalid ASN1 data in the given private key\")\n\t\t\tdefault:\n\t\t\t\terrStr = fmt.Sprintf(\"invalid private key: %s\", e)\n\t\t\t}\n\t\t\treturn cty.UnknownVal(cty.String), function.NewArgError(1, errors.New(errStr))\n\t\t}\n\t\tprivateKey, ok := rawKey.(*rsa.PrivateKey)\n\t\tif !ok {\n\t\t\treturn cty.UnknownVal(cty.String), function.NewArgErrorf(1, \"invalid private key type %t\", rawKey)\n\t\t}\n\n\t\tout, err := rsa.DecryptPKCS1v15(nil, privateKey, b)\n\t\tif err != nil {\n\t\t\treturn cty.UnknownVal(cty.String), fmt.Errorf(\"failed to decrypt: %s\", err)\n\t\t}\n\n\t\treturn cty.StringVal(string(out)), nil\n\t},\n})\n\n// Sha1Func contructs a function that computes the SHA1 hash of a given string\n// and encodes it with hexadecimal digits.\nvar Sha1Func = makeStringHashFunction(sha1.New, hex.EncodeToString)","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/lang/funcs/crypto.go#L169-L205","documentation":"Thrown by RsaDecryptFunc.Impl (the HCL rsadecrypt() builtin) when ssh.ParseRawPrivateKey fails with an error that is neither an asn1.SyntaxError nor asn1.StructuralError. The default branch formats the underlying Go error as 'invalid private key: <err>'. Note rsadecrypt only ever accepts an unencrypted RSA private key.","triggerScenarios":"rsadecrypt(ciphertext, key) where key is an OpenSSH-format key, an Ed25519/ECDSA key, a passphrase-protected key, a public key, or any non-RSA-PEM string.","commonSituations":"Modern ssh-keygen writes the OpenSSH private-key format which ParseRawPrivateKey rejects; using an Ed25519 key (not RSA) for rsadecrypt; passing the .pub half by mistake; key generated with a passphrase.","solutions":["Generate a traditional PEM RSA key: ssh-keygen -t rsa -m PEM -f key -N '' or openssl genrsa -out key 2048.","Ensure the key has no passphrase (decrypt with openssl rsa -in enc -out plain).","Confirm you pass the private half, not the public key, and that it is RSA (not Ed25519/ECDSA)."],"exampleFix":"# before\noutput \"pw\" { value = rsadecrypt(aws_kms_secrets.s.blob, file(\"~/.ssh/id_ed25519\")) }\n# after: generate an RSA PEM key without passphrase\n#   ssh-keygen -t rsa -m PEM -f rsa_key -N ''\noutput \"pw\" { value = rsadecrypt(aws_kms_secrets.s.blob, file(\"rsa_key\")) }","handlingStrategy":"validation","validationCode":"# validate the key is an unencrypted RSA PEM before rsadecrypt\nlocals {\n  key      = file(\"rsa_key\")\n  is_rsa   = strcontains(local.key, \"-----BEGIN RSA PRIVATE KEY-----\") || strcontains(local.key, \"BEGIN PRIVATE KEY\")\n  enc      = strcontains(local.key, \"ENCRYPTED\")\n}\ncheck \"rsa_key\" {\n  assert {\n    condition     = local.is_rsa && !local.enc\n    error_message = \"rsadecrypt needs an unencrypted PEM RSA private key\"\n  }\n}","typeGuard":"locals {\n  ok   = can(regex(\"-----BEGIN (RSA )?PRIVATE KEY-----\", local.key))\n  blob = local.ok ? rsadecrypt(var.cipher, local.key) : null\n}","tryCatchPattern":"locals { pw = try(rsadecrypt(var.cipher, file(\"rsa_key\")), null) }","preventionTips":["Generate keys specifically for rsadecrypt: ssh-keygen -t rsa -m PEM -N '' or openssl genrsa.","Never use Ed25519/ECDSA/OpenSSH-format keys with rsadecrypt (RSA-only).","Double-check you pass the private half, and keep it unencrypted."],"tags":["hcl","function","rsadecrypt","crypto","ssh"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}