readxl built against cpp11 0.5.4 segfaults at runtime when emitting a coercion warning. Built against cpp11 0.5.3 (same readxl source, same R,same compiler), it works. Demo below.
In readxl:
Problem observed in various settings:
Not reproduced on gcc anywhere (CRAN's gcc flavors and Linux/Windows GHA all pass). Not R-version-specific: R 4.5 and R 4.6 both crash with cpp11 0.5.4.
Demo notes:
- R 4.5 on any clang platform. (cpp11 0.5.3 doesn't compile against R 4.6 —
uses removed R_NamespaceRegistry — so R 4.5 is just where both versions
build.)
- readxl pinned to v1.4.5 (current CRAN release, predates the workaround).
cpp11 is header-only, so the buggy templates are baked into readxl.so at
install time; rebuild from source for each cpp11 version.
- Build with
-g -O0 for a clean, immediate segfault. At default -O2 the
failure mode varies on macOS (indefinite hang). My ~/.R/Makevars:
CFLAGS=-g -O0 -Wall
CXXFLAGS=-g -O0 -Wall
CXX11FLAGS=-g -O0 -Wall
CXX14FLAGS=-g -O0 -Wall
CXX17FLAGS=-g -O0 -Wall
F77=gfortran
FC=gfortran
Here are the two different setups. It's important to specify ?source?reinstall in these pak calls to force recompilation and pick up the ambient cpp11.
# --- cpp11 0.5.3 ---
pak::pkg_install("cpp11@0.5.3")
pak::pkg_install("tidyverse/readxl@v1.4.5?source&reinstall")
# --- cpp11 0.5.4 ---
pak::pkg_install("cpp11") # 0.5.4 from CRAN
pak::pkg_install("tidyverse/readxl@v1.4.5?source&reinstall")
This tickles the problem because we'll see some coercion warnings from forcing things to become logical.
library(readxl)
R.version.string
packageVersion("cpp11")
packageVersion("readxl")
read_excel(
readxl_example("type-me.xlsx"),
sheet = "logical_coercion",
col_types = c("logical", "skip")
)
With cpp11 4.5.3, all is well. Notice the coercion warnings.
library(readxl)
R.version.string
#> [1] "R version 4.5.3 (2026-03-11)"
packageVersion("cpp11")
#> [1] '0.5.3'
packageVersion("readxl")
#> [1] '1.4.5'
read_excel(
readxl_example("type-me.xlsx"),
sheet = "logical_coercion",
col_types = c("logical", "skip")
)
#> Warning: Expecting logical in A5 / R5C1: got a date
#> Warning: Expecting logical in A8 / R8C1: got 'cabbage'
#> # A tibble: 10 × 1
#> `maybe boolean?`
#> <lgl>
#> 1 NA
#> 2 FALSE
#> 3 TRUE
#> 4 NA
#> 5 TRUE
#> 6 FALSE
#> 7 NA
#> 8 TRUE
#> 9 FALSE
#> 10 FALSE
With cpp11 0.5.4, we see a segfault:
> library(readxl)
>
> R.version.string
[1] "R version 4.5.3 (2026-03-11)"
> packageVersion("cpp11")
[1] '0.5.4'
> packageVersion("readxl")
[1] '1.4.5'
> read_excel(
+ readxl_example("type-me.xlsx"),
+ sheet = "logical_coercion",
+ col_types = c("logical", "skip")
+ )
*** caught segfault ***
address 0xffff11000000, cause 'invalid permissions'
Traceback:
1: read_fun(path = path, sheet_i = sheet, limits = limits, shim = shim, col_names = col_names, col_types = col_types, na = na, trim_ws = trim_ws, guess_max = guess_max, progress = progress)
2: tibble::as_tibble(l, .name_repair = .name_repair)
3: set_readxl_names(read_fun(path = path, sheet_i = sheet, limits = limits, shim = shim, col_names = col_names, col_types = col_types, na = na, trim_ws = trim_ws, guess_max = guess_max, progress = progress), .name_repair = .name_repair)
4: read_excel_(path = path, sheet = sheet, range = range, col_names = col_names, col_types = col_types, na = na, trim_ws = trim_ws, skip = skip, n_max = n_max, guess_max = guess_max, progress = progress, .name_repair = .name_repair, format = format)
5: read_excel(readxl_example("type-me.xlsx"), sheet = "logical_coercion", col_types = c("logical", "skip"))
readxl built against cpp11 0.5.4 segfaults at runtime when emitting a coercion warning. Built against cpp11 0.5.3 (same readxl source, same R,same compiler), it works. Demo below.
In readxl:
cpp11::warning(fmt, args...)/cpp11::stop(fmt, args...)with helpers that pre-format the message into astd::string— bypassing cpp11's variadic-template forwarding entirely.Problem observed in various settings:
r-devel-linux-x86_64-{debian,fedora}-clang(segfault);r-release-macos-x86_64(segfault);Additional checks on
M1Mac(different presentation, but CRAN and I both think likely has same root cause). https://cran.r-project.org/web/checks/check_results_readxl.html. I also have an email from BDR and a May 15 deadline to fix.macos-latest(indefinite hang during vignette build, similar to CRAN M1Mac observation). Example: https://github.com/tidyverse/readxl/actions/runs/25193092291.Not reproduced on gcc anywhere (CRAN's gcc flavors and Linux/Windows GHA all pass). Not R-version-specific: R 4.5 and R 4.6 both crash with cpp11 0.5.4.
Demo notes:
uses removed
R_NamespaceRegistry— so R 4.5 is just where both versionsbuild.)
cpp11 is header-only, so the buggy templates are baked into
readxl.soatinstall time; rebuild from source for each cpp11 version.
-g -O0for a clean, immediate segfault. At default-O2thefailure mode varies on macOS (indefinite hang). My
~/.R/Makevars:Here are the two different setups. It's important to specify
?source?reinstallin these pak calls to force recompilation and pick up the ambient cpp11.This tickles the problem because we'll see some coercion warnings from forcing things to become logical.
With cpp11 4.5.3, all is well. Notice the coercion warnings.
With cpp11 0.5.4, we see a segfault: