hashicorp/terraform · error
failed to parse certificate %q: %s
Error message
failed to parse certificate %q: %s
What it means
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.
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 c9def3e214)
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.
Example fix
// before
connection {
private_key = file("~/.ssh/id_rsa")
certificate = file("~/.ssh/id_rsa.pub") # wrong: this is a public key, not a cert
}
// after
connection {
private_key = file("~/.ssh/id_rsa")
certificate = file("~/.ssh/id_rsa-cert.pub")
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the certificate is a real SSH certificate (not a plain public key)
func validateSSHCertificate(cert string) error {
pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(cert))
if err != nil {
return fmt.Errorf("certificate is not parseable: %w", err)
}
// A real certificate has a CertType; a plain public key does not
if _, ok := pk.(*ssh.Certificate); !ok {
return errors.New("the certificate value is a plain public key, not an SSH certificate")
}
return nil
} Type guard
// Type guard: check if the parsed key is actually a certificate
func isSSHCertificate(certStr string) bool {
pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(certStr))
if err != nil {
return false
}
_, ok := pk.(*ssh.Certificate)
return ok
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
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 parse private key %q: %s
- failed to create cert signer %q: %s
- SSH authentication failed (%s@%s): %w
- Error creating new client connection via proxy: %s
- Error connecting to bastion: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/6b139cda05b0840f.
Report an issue: GitHub.