{"record":{"id":"6b139cda05b0840f","repo":"hashicorp/terraform","slug":"failed-to-parse-certificate-q-s","errorCode":null,"errorMessage":"failed to parse certificate %q: %s","messagePattern":"failed to parse certificate %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/communicator/ssh/provisioner.go","lineNumber":405,"sourceCode":"\t}\n\n\tif opts.sshAgent != nil {\n\t\tconf.Auth = append(conf.Auth, opts.sshAgent.Auth())\n\t}\n\n\treturn conf, nil\n}\n\n// Create a Cert Signer and return ssh.AuthMethod\nfunc signCertWithPrivateKey(pk string, certificate string) (ssh.AuthMethod, error) {\n\trawPk, err := ssh.ParseRawPrivateKey([]byte(pk))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse private key %q: %s\", pk, err)\n\t}\n\n\tpcert, _, _, _, err := ssh.ParseAuthorizedKey([]byte(certificate))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse certificate %q: %s\", certificate, err)\n\t}\n\n\tusigner, err := ssh.NewSignerFromKey(rawPk)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create signer from raw private key %q: %s\", rawPk, err)\n\t}\n\n\tucertSigner, err := ssh.NewCertSigner(pcert.(*ssh.Certificate), usigner)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create cert signer %q: %s\", usigner, err)\n\t}\n\n\treturn ssh.PublicKeys(ucertSigner), nil\n}\n\nfunc readPrivateKey(pk string) (ssh.AuthMethod, error) {\n\t// We parse the private key on our own first so that we can\n\t// show a nicer error if the private key has a password.","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/communicator/ssh/provisioner.go#L387-L423","documentation":"Raised in signCertWithPrivateKey when ssh.ParseAuthorizedKey fails parsing the certificate string. This occurs in the certificate-based auth path (both private_key and certificate configured). The certificate must be a valid SSH public key certificate in authorized_keys format for the cert signer to be constructed.","triggerScenarios":"The certificate value is malformed, is a plain public key rather than a certificate, is truncated/corrupted, or is in an unsupported format. ParseAuthorizedKey expects the authorized_keys text format including the key type prefix.","commonSituations":"The certificate attribute points to the wrong file (e.g. a .pub key instead of a -cert.pub certificate), the certificate is expired or revoked (though parsing would still succeed), the cert content was truncated during copy-paste, or the format does not include the 'ssh-rsa-cert-v01@openssh.com' type prefix.","solutions":["Verify the certificate value is an actual SSH certificate (not a plain public key) — it should have '-cert' in the key type prefix.","Ensure the certificate file path is correct (typically id_rsa-cert.pub or id_ed25519-cert.pub).","Confirm the certificate content is complete and untruncated.","Check with ssh-keygen -L -f certfile that the certificate is valid."],"exampleFix":"// before\nconnection {\n  private_key = file(\"~/.ssh/id_rsa\")\n  certificate = file(\"~/.ssh/id_rsa.pub\") # wrong: this is a public key, not a cert\n}\n\n// after\nconnection {\n  private_key = file(\"~/.ssh/id_rsa\")\n  certificate = file(\"~/.ssh/id_rsa-cert.pub\")\n}","handlingStrategy":"validation","validationCode":"// Validate the certificate is a real SSH certificate (not a plain public key)\nfunc validateSSHCertificate(cert string) error {\n    pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(cert))\n    if err != nil {\n        return fmt.Errorf(\"certificate is not parseable: %w\", err)\n    }\n    // A real certificate has a CertType; a plain public key does not\n    if _, ok := pk.(*ssh.Certificate); !ok {\n        return errors.New(\"the certificate value is a plain public key, not an SSH certificate\")\n    }\n    return nil\n}","typeGuard":"// Type guard: check if the parsed key is actually a certificate\nfunc isSSHCertificate(certStr string) bool {\n    pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(certStr))\n    if err != nil {\n        return false\n    }\n    _, ok := pk.(*ssh.Certificate)\n    return ok\n}","tryCatchPattern":null,"preventionTips":["Use the -cert.pub file, not the .pub file, for the certificate attribute.","Verify the certificate with ssh-keygen -L -f certfile.","Ensure the certificate content is complete and not truncated."],"tags":["ssh","certificate","authentication","authorized-key","terraform"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}