hashicorp/terraform · error
can not read leafPassphraseBytes from %s
Error message
can not read leafPassphraseBytes from %s
What it means
Returned during InstancePrincipalWithCerts setup when getCertificateFileBytes fails to read the leaf passphrase file. The code first checks if a file named 'leaf_passphrase' exists (note: the stat check uses certsDir + '/leaf_passphrase' but the read uses certsDir + 'leaf_passphrase' without a separator — a likely path-joining bug in the source). If the stat succeeds but the read fails, this error is returned.
Source
Thrown at internal/backend/remote-state/oci/auth.go:215
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,
}
cfg, err := auth.InstancePrincipalConfigurationWithCerts(common.StringToRegion(p.region), leafCertificateBytes, leafPassphraseBytes, leafPrivateKeyBytes, intermediateCertificatesBytes)
if err != nil {
return nil, err
}
logger.Debug(" Configuration provided by: %s", cfg)
View on GitHub (pinned to d32a084675)
Solutions
- Remove the leaf_passphrase file from the certs directory if your test cert has no passphrase — the code only attempts to read it when it exists.
- If a passphrase is needed, ensure the file is readable AND be aware of the path-joining bug: the file may need to exist at the path formed by certsDir+'leaf_passphrase' (no separator) rather than certsDir+'/leaf_passphrase'.
- Set test_certificates_location to a directory where the concatenation resolves correctly.
- Report the path-joining bug upstream (certsDir + 'leaf_passphrase' should be filepath.Join(certsDir, 'leaf_passphrase')).
Example fix
// before // leaf_passphrase file exists, triggering read at buggy path // after (if no passphrase needed): rm $test_certificates_location/leaf_passphrase terraform init // NOTE: source has a bug: filepath.Join(certsDir+"leaf_passphrase") should be // filepath.Join(certsDir, "leaf_passphrase") — the stat check uses '/leaf_passphrase' // but the read uses 'leaf_passphrase' without separator.
Defensive patterns
Strategy: validation
Validate before calling
// Be aware of the path-joining bug in the source:
// stat checks: certsDir + "/leaf_passphrase"
// read checks: certsDir + "leaf_passphrase" (no separator)
// The safest approach: remove leaf_passphrase if not needed.
func validatePassphraseFile(certsDir string) error {
passphrasePath := filepath.Join(certsDir, "leaf_passphrase")
if _, err := os.Stat(passphrasePath); err == nil {
// File exists — the code will try to read it.
// Warn about the path-joining bug.
log.Printf("WARNING: leaf_passphrase exists; source code has a path-joining bug that may cause read failure")
}
return nil
} Try / catch
// Pre-check and remove if unnecessary:
p := filepath.Join(certsDir, "leaf_passphrase")
if _, err := os.Stat(p); err == nil {
if !passphraseRequired {
os.Remove(p) // avoid triggering the buggy read path
}
} Prevention
- Remove leaf_passphrase from the certs directory if your test key has no passphrase.
- Be aware of the source code bug: the stat check uses '/leaf_passphrase' but the read uses 'leaf_passphrase' without separator.
- Report the path-joining bug upstream if it affects your workflow.
When it happens
Trigger: auth="InstancePrincipalWithCerts" is set, the file {certsDir}/leaf_passphrase exists (so the stat check passes), but reading it fails — or it succeeds at an unexpected path due to the missing path separator in the read call (certsDir + 'leaf_passphrase' vs certsDir + '/leaf_passphrase').
Common situations: A leaf_passphrase file exists in the certs dir but the path concatenation bug causes the read to look in the wrong location (parent directory); the file exists but has restrictive permissions; user accidentally created a leaf_passphrase file not realizing it triggers this code path.
Related errors
- can not read leaf certificate from %s
- can not read leaf private key from %s
- can not read intermediate certificate from %s
- can't form absolute path of %s: %v
- can't read %s: %v
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/8ced2a7035a0c67c.
Report an issue: GitHub.