{"record":{"id":"be28f173b497cc8d","repo":"hashicorp/terraform","slug":"can-not-read-private-key-from-s-error-q","errorCode":null,"errorMessage":"can not read private key from: '%s', Error: %q","messagePattern":"can not read private key from: '(.+?)', Error: %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/oci/auth.go","lineNumber":147,"sourceCode":"\tfingerprint, err := p.KeyFingerprint()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn fmt.Sprintf(\"%s/%s/%s\", tenancy, user, fingerprint), nil\n}\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 == \"\" {","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/oci/auth.go#L129-L165","documentation":"Returned by PrivateRSAKey() when os.ReadFile fails to read the PEM file at private_key_path. The backend resolves the path via expandPath, attempts to read the file, and wraps the underlying I/O error. The file must contain a PEM-encoded RSA private key.","triggerScenarios":"Backend block has 'private_key_path' set but the file does not exist, is not readable (permission denied), or the path is wrong (relative path resolves to an unexpected directory, ~ not expanded, wrong working directory).","commonSituations":"Path uses ~ but expandPath doesn't resolve it in the user's context; path is relative to a different working directory than where terraform runs; file permission is too restrictive; path was correct in CI but wrong locally; typo in the path string; file is outside the container/volume mount in containerized runs.","solutions":["Use an absolute path for private_key_path to avoid working-directory ambiguity.","Verify the file exists and is readable: ls -la /full/path/to/key.pem; chmod 600 if needed.","If running in a container or CI, ensure the key file is mounted/copied into the environment and the path matches.","Switch to the inline 'private_key' attribute (with \\n-escaped PEM) if file access is unreliable in the environment.","Check that expandPath resolves ~ correctly — if unsure, replace ~ with the full home directory path."],"exampleFix":"// before\nbackend \"oci\" {\n  private_key_path = \"~/keys/oci_key.pem\"\n}\n\n// after\nbackend \"oci\" {\n  private_key_path = \"/home/user/keys/oci_key.pem\"\n}\n\n// or inline:\nbackend \"oci\" {\n  private_key = \"-----BEGIN RSA PRIVATE KEY-----\\nMIIE...\\n-----END RSA PRIVATE KEY-----\"\n}","handlingStrategy":"validation","validationCode":"func validatePrivateKeyPath(path string) error {\n    if path == \"\" {\n        return nil // handled by other validation\n    }\n    abs, err := filepath.Abs(expandPath(path))\n    if err != nil {\n        return fmt.Errorf(\"cannot resolve private_key_path: %w\", err)\n    }\n    info, err := os.Stat(abs)\n    if err != nil {\n        return fmt.Errorf(\"private_key_path not accessible: %w\", err)\n    }\n    if info.IsDir() {\n        return fmt.Errorf(\"private_key_path is a directory, not a file\")\n    }\n    if info.Mode().Perm()&0400 == 0 {\n        return fmt.Errorf(\"private_key_path is not readable\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Validate key file before terraform init:\nif err := validatePrivateKeyPath(cfg.PrivateKeyPath); err != nil {\n    log.Fatal(err)\n}","preventionTips":["Always use absolute paths for private_key_path in backend config.","Verify file existence and permissions in a pre-init step.","In CI, inject the key as a file via secrets manager and validate it before running terraform."],"tags":["oci","authentication","filesystem","private-key","terraform-backend","io"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}