Skip to content
Latchkey

Ruby gem build "fatal error: header file not found" in CI

A gem’s C extension #includes a header that ships in a library’s development package. The runtime library may be present, but the -dev (or -devel) package that provides the header is not, so the compiler cannot find the file.

What this error means

gem install or bundle install dies during compilation with "fatal error: <something>.h: No such file or directory" and then "make failed". The named header points straight at the missing -dev package.

bundler
compiling ruby_http_parser.c
ext/http11/http11_parser.c:13:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
         ^~~~~~~~~~~~~~~
1 error generated.
make failed, exit code 2

Common causes

The development headers package is not installed

The runtime .so is present but the -dev/-devel package that ships the .h files is not, so the include fails.

Headers are in a non-default path

The library is installed somewhere the compiler does not search, so the header is effectively invisible without extra build flags.

How to fix it

Install the matching -dev package

Map the missing header to its development package and install it.

Terminal
# openssl/ssl.h -> libssl-dev (Debian/Ubuntu)
sudo apt-get update
sudo apt-get install -y libssl-dev
bundle install --jobs 4

Point the build at non-default header paths

If the library lives outside the default search path, pass its include/lib dirs to the gem build.

Terminal
bundle config build.example-gem \
  "--with-opt-include=/usr/local/opt/openssl/include \
   --with-opt-lib=/usr/local/opt/openssl/lib"
bundle install

How to prevent it

  • Install the -dev packages for every native gem you depend on in CI.
  • Document the system dependencies your gems require so new runners include them.
  • Use a runner image that bundles common -dev libraries.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →