{"record":{"id":"69341f6fdc417254","repo":"hashicorp/terraform","slug":"can-not-get-private-key-or-private-key-path-from-t","errorCode":null,"errorMessage":"can not get private_key or private_key_path from Terraform configuration","messagePattern":"can not get private_key or private_key_path from Terraform configuration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/oci/auth.go","lineNumber":152,"sourceCode":"}\n\nfunc (p ociAuthConfigProvider) PrivateRSAKey() (key *rsa.PrivateKey, err error) {\n\n\tif p.privateKey != \"\" {\n\t\tkeyData := strings.ReplaceAll(p.privateKey, \"\\\\n\", \"\\n\") // Ensure \\n is replaced by actual newlines\n\t\treturn common.PrivateKeyFromBytesWithPassword([]byte(keyData), []byte(p.privateKeyPassword))\n\t}\n\n\tif p.privateKeyPath != \"\" {\n\t\tresolvedPath := expandPath(p.privateKeyPath)\n\t\tpemFileContent, readFileErr := os.ReadFile(resolvedPath)\n\t\tif readFileErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"can not read private key from: '%s', Error: %q\", p.privateKeyPath, readFileErr)\n\t\t}\n\t\treturn common.PrivateKeyFromBytesWithPassword(pemFileContent, []byte(p.privateKeyPassword))\n\t}\n\n\treturn nil, fmt.Errorf(\"can not get private_key or private_key_path from Terraform configuration\")\n}\n\nfunc (p ociAuthConfigProvider) getConfigProviders() ([]common.ConfigurationProvider, error) {\n\tvar configProviders []common.ConfigurationProvider\n\tlogger := logWithOperation(\"AuthConfigProvider\")\n\tlogger.Debug(fmt.Sprintf(\"Using %s authentication\", p.authType))\n\tswitch strings.ToLower(p.authType) {\n\tcase strings.ToLower(AuthAPIKeySetting):\n\t\t// No additional config providers needed\n\tcase strings.ToLower(AuthInstancePrincipalSetting):\n\n\t\tlogger.Info(\"Attempting to authenticate using instance principal credentials\")\n\t\tif p.region == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"unable to determine region from Terraform backend configuration while using Instance Principal\")\n\t\t}\n\n\t\t// Used to modify InstancePrincipal auth clients so that `accept_local_certs` is honored for auth clients as well\n\t\tinstancePrincipalAuthClientModifier := func(client common.HTTPRequestDispatcher) (common.HTTPRequestDispatcher, error) {","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/oci/auth.go#L134-L170","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nbackend \"oci\" {\n  auth         = \"api_key\"\n  tenancy_ocid = \"ocid1.tenancy.oc1..aaaa...\"\n  user_ocid    = \"ocid1.user.oc1..aaaa...\"\n  fingerprint  = \"aa:bb:...\"\n  region       = \"us-phoenix-1\"\n}\n\n// after\nbackend \"oci\" {\n  auth            = \"api_key\"\n  tenancy_ocid    = \"ocid1.tenancy.oc1..aaaa...\"\n  user_ocid       = \"ocid1.user.oc1..aaaa...\"\n  fingerprint     = \"aa:bb:...\"\n  region          = \"us-phoenix-1\"\n  private_key_path = \"/home/user/.oci/oci_api_key.pem\"\n}","handlingStrategy":"validation","validationCode":"func validateOCIBackendConfig(cfg BackendConfig) error {\n    if strings.EqualFold(cfg.Auth, \"APIKey\") {\n        if cfg.PrivateKey == \"\" && cfg.PrivateKeyPath == \"\" {\n            return fmt.Errorf(\"either private_key or private_key_path is required for API key auth\")\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Pre-init validation:\nif err := validateOCIBackendConfig(backendCfg); err != nil {\n    log.Fatal(err)\n}","preventionTips":["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."],"tags":["oci","authentication","configuration","private-key","terraform-backend","api-key"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}