hashicorp/terraform · error

can not read leaf private key from %s

Error message

can not read leaf private key from %s

What it means

Returned during InstancePrincipalWithCerts setup when getCertificateFileBytes fails to read the leaf private key file (ip_key.pem). This file must accompany ip_cert.pem in the certificates directory and is needed to establish the instance principal mTLS connection.

Source

Thrown at internal/backend/remote-state/oci/auth.go:208

		if p.region == "" {
			return nil, fmt.Errorf("unable to determine region from Terraform backend configuration while using Instance Principal with certificates")
		}

		defaultCertsDir, err := os.Getwd()
		if err != nil {
			return nil, fmt.Errorf("can not get working directory for current os platform")
		}

		certsDir := filepath.Clean(getEnvSettingWithDefault("test_certificates_location", defaultCertsDir))
		leafCertificateBytes, err := getCertificateFileBytes(filepath.Join(certsDir, "ip_cert.pem"))
		if err != nil {
			return nil, fmt.Errorf("can not read leaf certificate from %s", filepath.Join(certsDir, "ip_cert.pem"))
		}

		leafPrivateKeyBytes, err := getCertificateFileBytes(filepath.Join(certsDir, "ip_key.pem"))
		if err != nil {
			return nil, fmt.Errorf("can not read leaf private key from %s", filepath.Join(certsDir, "ip_key.pem"))
		}

		leafPassphraseBytes := []byte{}
		if _, err := os.Stat(certsDir + "/leaf_passphrase"); !os.IsNotExist(err) {
			leafPassphraseBytes, err = getCertificateFileBytes(filepath.Join(certsDir + "leaf_passphrase"))
			if err != nil {
				return nil, fmt.Errorf("can not read leafPassphraseBytes from %s", filepath.Join(certsDir+"leaf_passphrase"))
			}
		}

		intermediateCertificateBytes, err := getCertificateFileBytes(filepath.Join(certsDir, "intermediate.pem"))
		if err != nil {
			return nil, fmt.Errorf("can not read intermediate certificate from %s", filepath.Join(certsDir, "intermediate.pem"))
		}

		intermediateCertificatesBytes := [][]byte{
			intermediateCertificateBytes,
		}

View on GitHub (pinned to d32a084675)

Solutions

  1. Ensure ip_key.pem exists alongside ip_cert.pem in the certs directory.
  2. Set test_certificates_location to the directory containing the complete cert set (ip_cert.pem, ip_key.pem, intermediate.pem).
  3. Regenerate the full test certificate bundle if the key is missing.
  4. Verify read permissions on the file.

Example fix

// before
// certs dir has ip_cert.pem but not ip_key.pem

// after
export test_certificates_location=/home/user/test-certs
# ensure all files present:
ls $test_certificates_location/{ip_cert.pem,ip_key.pem,intermediate.pem}
Defensive patterns

Strategy: validation

Validate before calling

func validateTestCerts(certsDir string) error {
    files := []string{"ip_cert.pem", "ip_key.pem", "intermediate.pem"}
    for _, f := range files {
        if _, err := os.ReadFile(filepath.Join(certsDir, f)); err != nil {
            return fmt.Errorf("cannot read %s: %w", f, err)
        }
    }
    return nil
}

Try / catch

// Pre-validate before terraform init:
if err := validateTestCerts(certsDir); err != nil {
    log.Fatal(err)
}

Prevention

When it happens

Trigger: auth="InstancePrincipalWithCerts" is set and {certsDir}/ip_key.pem is missing, unreadable, or the directory is wrong.

Common situations: Test certificate set is incomplete (cert present but key missing); test_certificates_location points to wrong dir; file permission issue; certs generated on another machine and not fully copied.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/3fdf1b92bb45b10b. Report an issue: GitHub.