hashicorp/terraform · error
can not get private_key or private_key_path from Terraform c
Error message
can not get private_key or private_key_path from Terraform configuration
What it means
Returned by PrivateRSAKey() when neither 'private_key' (inline PEM string) nor 'private_key_path' (file path) is configured. At least one is required for API key authentication to produce an RSA signing key.
Source
Thrown at internal/backend/remote-state/oci/auth.go:152
}
func (p ociAuthConfigProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {
if p.privateKey != "" {
keyData := strings.ReplaceAll(p.privateKey, "\\n", "\n") // Ensure \n is replaced by actual newlines
return common.PrivateKeyFromBytesWithPassword([]byte(keyData), []byte(p.privateKeyPassword))
}
if p.privateKeyPath != "" {
resolvedPath := expandPath(p.privateKeyPath)
pemFileContent, readFileErr := os.ReadFile(resolvedPath)
if readFileErr != nil {
return nil, fmt.Errorf("can not read private key from: '%s', Error: %q", p.privateKeyPath, readFileErr)
}
return common.PrivateKeyFromBytesWithPassword(pemFileContent, []byte(p.privateKeyPassword))
}
return nil, fmt.Errorf("can not get private_key or private_key_path from Terraform configuration")
}
func (p ociAuthConfigProvider) getConfigProviders() ([]common.ConfigurationProvider, error) {
var configProviders []common.ConfigurationProvider
logger := logWithOperation("AuthConfigProvider")
logger.Debug(fmt.Sprintf("Using %s authentication", p.authType))
switch strings.ToLower(p.authType) {
case strings.ToLower(AuthAPIKeySetting):
// No additional config providers needed
case strings.ToLower(AuthInstancePrincipalSetting):
logger.Info("Attempting to authenticate using instance principal credentials")
if p.region == "" {
return nil, fmt.Errorf("unable to determine region from Terraform backend configuration while using Instance Principal")
}
// Used to modify InstancePrincipal auth clients so that `accept_local_certs` is honored for auth clients as well
instancePrincipalAuthClientModifier := func(client common.HTTPRequestDispatcher) (common.HTTPRequestDispatcher, error) {View on GitHub (pinned to d32a084675)
Solutions
- Add 'private_key_path' pointing to the PEM file, or 'private_key' with the PEM content (\n-escaped if inline).
- If the key lives in the OCI config file, switch auth to 'security_token' or use config_file_profile so the SDK resolves the key path from the profile.
- If using a secrets manager or templating system, verify the private_key attribute renders non-empty at runtime.
- For CI, ensure the key is injected as an environment variable or file before terraform init.
Example fix
// before
backend "oci" {
auth = "api_key"
tenancy_ocid = "ocid1.tenancy.oc1..aaaa..."
user_ocid = "ocid1.user.oc1..aaaa..."
fingerprint = "aa:bb:..."
region = "us-phoenix-1"
}
// after
backend "oci" {
auth = "api_key"
tenancy_ocid = "ocid1.tenancy.oc1..aaaa..."
user_ocid = "ocid1.user.oc1..aaaa..."
fingerprint = "aa:bb:..."
region = "us-phoenix-1"
private_key_path = "/home/user/.oci/oci_api_key.pem"
} Defensive patterns
Strategy: validation
Validate before calling
func validateOCIBackendConfig(cfg BackendConfig) error {
if strings.EqualFold(cfg.Auth, "APIKey") {
if cfg.PrivateKey == "" && cfg.PrivateKeyPath == "" {
return fmt.Errorf("either private_key or private_key_path is required for API key auth")
}
}
return nil
} Try / catch
// Pre-init validation:
if err := validateOCIBackendConfig(backendCfg); err != nil {
log.Fatal(err)
} Prevention
- Define the complete set of API key auth fields in your backend template.
- Use CI checks to verify the backend block has all required attributes.
- If using templated backend config, add a post-render validation step to ensure no fields are empty.
When it happens
Trigger: Backend block uses auth="api_key" but neither private_key nor private_key_path is present. The method falls through both if-checks and returns this catch-all error.
Common situations: User set up tenancy_ocid, user_ocid, fingerprint, region but forgot the key entirely; user expected the key to come from the OCI config file but auth is api_key (which uses inline provider fields); user removed the key for security review and didn't restore it; config templating stripped the private_key attribute during rendering.
Related errors
- can not read private key from: '%s', Error: %q
- unable to determine region from Terraform backend configurat
- unable to determine region from Terraform backend configurat
- can not read leaf private key from %s
- can not get %s from Terraform configuration (SecurityToken)
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/69341f6fdc417254.
Report an issue: GitHub.