hashicorp/terraform · error
failed to parse certificate
Error message
failed to parse certificate %q: %s
What it means
In signCertWithPrivateKey, after parsing the private key, the certificate string is parsed via ssh.ParseAuthorizedKey. If the certificate is not a valid SSH authorized key / certificate format, parsing fails. SECURITY NOTE: the error message interpolates the full certificate material via %q.
Solutions
- Verify you are providing an SSH certificate (filename typically ends in -cert.pub), not a plain public key.
- Ensure the certificate string is complete and untruncated — it should be a single line starting with the key type (e.g., ssh-rsa-cert-v01@openssh.com).
- Check for whitespace/newline corruption if loading from a secrets manager or environment variable.
- Regenerate the certificate from the CA if it may be corrupt: ssh-keygen -s ca_key -I identity id_rsa.pub.
Example fix
# before — using plain public key instead of certificate
connection {
certificate = file("~/.ssh/id_rsa.pub") # wrong file
private_key = file("~/.ssh/id_rsa")
}
# after — using the actual signed certificate
connection {
certificate = file("~/.ssh/id_rsa-cert.pub")
private_key = file("~/.ssh/id_rsa")
} Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate the certificate is a valid SSH certificate (not just a public key)
import "golang.org/x/crypto/ssh"
func validateSSHCertificate(cert string) error {
key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(cert))
if err != nil {
return fmt.Errorf("certificate not parseable: %w", err)
}
sshCert, ok := key.(*ssh.Certificate)
if !ok {
return errors.New("provided value is a public key, not a certificate")
}
_ = sshCert
return nil
} Type guard
func isSSHCertificate(cert string) bool {
key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(cert))
if err != nil {
return false
}
_, ok := key.(*ssh.Certificate)
return ok
} Prevention
- Always reference -cert.pub files for certificates, not .pub files.
- Verify certificates with ssh-keygen -L -f <cert-file> before use.
- Ensure certificate and key come from the same key pair.
- Avoid logging certificate material in error output.
When it happens
Trigger: Providing a certificate value to the SSH connection that is not a valid SSH certificate. Triggered by: providing a regular public key instead of a certificate (missing -cert.pub), a corrupt or truncated certificate string, a certificate in an unsupported format, or certificate text with mangled whitespace/newlines.
Common situations: User references id_rsa.pub (the public key) instead of id_rsa-cert.pub (the actual certificate). Certificate was copied with line breaks inserted by a terminal or secrets manager. Certificate generated by a CA in an incompatible format. Using a host certificate where a user certificate is expected.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to create cert signer
- failed to parse private key
- failed to create signer from raw private key
- Failed to parse ssh private key
- failed to write temp known_hosts file
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/6b139cda05b0840f.
Report an issue: GitHub.
Appendix: source
Thrown at internal/communicator/ssh/provisioner.go:405
}
if opts.sshAgent != nil {
conf.Auth = append(conf.Auth, opts.sshAgent.Auth())
}
return conf, nil
}
// Create a Cert Signer and return ssh.AuthMethod
func signCertWithPrivateKey(pk string, certificate string) (ssh.AuthMethod, error) {
rawPk, err := ssh.ParseRawPrivateKey([]byte(pk))
if err != nil {
return nil, fmt.Errorf("failed to parse private key %q: %s", pk, err)
}
pcert, _, _, _, err := ssh.ParseAuthorizedKey([]byte(certificate))
if err != nil {
return nil, fmt.Errorf("failed to parse certificate %q: %s", certificate, err)
}
usigner, err := ssh.NewSignerFromKey(rawPk)
if err != nil {
return nil, fmt.Errorf("failed to create signer from raw private key %q: %s", rawPk, err)
}
ucertSigner, err := ssh.NewCertSigner(pcert.(*ssh.Certificate), usigner)
if err != nil {
return nil, fmt.Errorf("failed to create cert signer %q: %s", usigner, err)
}
return ssh.PublicKeys(ucertSigner), nil
}
func readPrivateKey(pk string) (ssh.AuthMethod, error) {
// We parse the private key on our own first so that we can
// show a nicer error if the private key has a password.View on GitHub (pinned to d32a084675)