Diagnosing R Package Installation Failures on Linux, macOS, and Windows
Fix R install.packages failures by matching missing system headers, compiler toolchains, and repositories to your running R version.
05 Apr 2026, 08:31 UTC

Problem and takeaway
You run install.packages("curl") in the R console and the process ends with configuration failed, cannot find -lcurl, or xml2-config not found. The package source downloads but never compiles, so library("curl") cannot load it.
The useful takeaway is that most R package installation failures are not defects in R or the package. They usually come from one of three conditions: missing operating-system development headers, an absent or mismatched compiler toolchain, or a package repository that does not match your running R version.
Recognizable conditions and likely causes
| Symptom in R | Likely cause | First check |
|---|---|---|
configuration failed or cannot find -lcurl |
Missing OS development headers for libcurl | Run system("curl-config --version") in R |
xml2-config not found |
Missing libxml2 development headers | Run system("xml2-config --version") in R |
gcc: command not found or clang error |
Absent C/C++ or Fortran compiler | Run Sys.getenv(c("CC", "CXX", "FC")) and Sys.which("gcc") |
package is not available for this version of R |
Repository/R version mismatch | Check R.version.string and getOption("repos") |
cannot remove existing package or locked library |
Another R session holds the directory or write permissions are denied | List active R processes and inspect .libPaths() ownership |
DLL load failed or symbol not found after install |
ABI mismatch from mixed R versions or binary/source installs | Confirm one repository and one R version for the package and its dependencies |
Ordered checks
-
Check the running R version and package repository
Run this in the R console:
R.version.string getOption("repos") .libPaths()Expected result:
R.version.stringshows a version such as 4.4.x, andgetOption("repos")lists a CRAN mirror or RSPM URL. If the repository advertises binaries for R 4.2 while you run R 4.4, source installation may fail or pull incompatible dependencies. -
Check for missing system development headers
Run this in the R console:
system("curl-config --version") system("xml2-config --version")Expected result: each command returns a version string and exits with status 0. A
sh: curl-config: not foundmessage means the OS development package is absent. -
Check the compiler toolchain
Run this in the R console:
Sys.getenv(c("CC", "CXX", "FC")) Sys.which("gcc") Sys.which("gfortran") Sys.which("make")Expected result: each
Sys.whichcall returns a file path, not an empty string. On Windows, R 4.0 and later generally require Rtools matched to the R major.minor line; on macOS, the Xcode Command Line Tools supplyclangandmake; on Linux,build-essentialor equivalent suppliesgcc,g++, andmake. -
Check library path and locks
Run this in the R console:
.libPaths()
Expected result: the first path is writable by your user account. If another R session or RStudio project has the package loaded, the directory may be locked and removal or overwriting will fail.
Fixes tied to findings
Missing development headers
Install the matching OS package, then retry the R installation. Run these commands in a terminal, not the R console. You typically need administrator privileges, for example sudo on Debian or Ubuntu, to modify system directories.
| Operating system | Command | Package supplied |
|---|---|---|
| Debian or Ubuntu | sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev libxml2-dev |
curl-config, xml2-config, and header files |
| RHEL, Fedora, or AlmaLinux | sudo dnf install -y libcurl-devel libxml2-devel |
curl-config, xml2-config, and header files |
| macOS with Homebrew | brew install curl libxml2 |
Headers and libraries; link with PKG_CONFIG_PATH if Homebrew is not in the default search path |
Risk: installing system packages changes the host and may affect other users. Verify the exact package name for your release before running the command, because names differ across distributions and versions.
After the system package installs, return to the R console and run:
install.packages("curl")
library("curl")
Expected check: library("curl") loads without a DLL load failed or symbol not found error.
Missing compiler toolchain
Install the compiler suite for your platform, then confirm it is on PATH before installing compiled R packages.
- Debian or Ubuntu:
sudo apt-get install -y build-essential gfortran - RHEL or Fedora:
sudo dnf install -y gcc gcc-c++ gcc-gfortran make - macOS:
xcode-select --installinstalls the Command Line Tools - Windows: download and install Rtools matching your R version, for example Rtools43 for R 4.3.x, then restart R so
Sys.which("gcc")returns a path
Required permission: administrator or equivalent to write to system directories. Risk: installing Rtools on Windows modifies the system PATH; confirm the installer does not shadow an existing toolchain you need for other projects.
Repository and R version mismatch
If getOption("repos") points to a mirror built for an older R line, switch to a repository that matches R.version.string. Run this in the R console:
options(repos = c(CRAN = "https://cloud.r-project.org/"))
install.packages("httr")
Placeholder: replace https://cloud.r-project.org/ with your organization's internal RSPM or CRAN mirror if required. Expected check: install.packages downloads a binary or source package labeled for your R major.minor version.
Locked library or permission denied
Close all other R sessions and RStudio projects that use the library. If the path is still locked, inspect ownership:
Sys.getenv("R_LIBS_USER")
.libPaths()
If you do not own the first library path, create a personal library and add it to the front of the search path:
personal_lib <- file.path(Sys.getenv("HOME"), "R-libs")
dir.create(personal_lib, recursive = TRUE, showWarnings = FALSE)
.libPaths(c(personal_lib, .libPaths()))
Then install with install.packages("curl", lib = personal_lib). Required permission: write access to your home directory. Risk: packages installed to a personal library are not visible to other system users unless they add the same path.
ABI mismatch after installation
If library("curl") loads but a dependent package throws symbol not found, the package and its dependencies were likely built under different R versions or from mixed repositories. Reinstall the package and its dependencies from one repository under the same R version:
remove.packages("curl")
install.packages("curl", dependencies = TRUE)
Expected check: library("curl") and library("httr") both load without symbol errors.
Rollback
This guide changes system state when you install OS development packages or R packages. To remove an OS development package on Debian or Ubuntu:
sudo apt-get remove --purge libcurl4-openssl-dev libxml2-dev
To remove an R package from a personal library:
remove.packages("curl", lib = personal_lib)
Rollback does not restore configurations changed by other installed software.
Escalation criteria
Escalate to a system administrator or package maintainer when:
- Multiple packages fail with the same missing header after you install the matching development package
- The error persists across CRAN, RSPM, and source installation, suggesting a broken compiler or system library
- You cannot obtain administrator privileges to install system packages and no personal library option is available
- A compiled dependency fails recursively and the dependency chain is not documented in the package README
Limitations and verification
This guide covers source installation from CRAN. Bioconductor and GitHub packages may require additional system libraries not listed here. System package names vary by distribution and release; confirm the exact name before running an install command. The steps assume a standard R installation and do not address RStudio IDE library settings unless they mirror the R console behavior described above.
Practical verification after any fix:
- Run
R.version.string,getOption("repos"), and.libPaths()to confirm the environment. - Run
install.packages("curl")and thenlibrary("curl"). - On Windows, confirm
Sys.which("make")andSys.which("gcc")return paths; on macOS or Linux, confirmgccandgfortranare on PATH.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.