Question

How to Fix Ruby Gem Native Extension Errors: Can't Find Header Files

rubymysqlrubygems

Question

I am using Fedora 14 with MySQL Server 5.1.42 installed and running.

When I try to install the Ruby MySQL gem as the root user:

gem install mysql

I get this error:

Building native extensions. This could take a while...
ERROR: Error installing mysql:
    ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb
mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h

Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/mysql-2.8.1 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/mysql-2.8.1/ext/mysql_api/gem_make.out

What is causing this error? Ruby 1.8.7 and RubyGems 1.3.7 are already installed.

Short Answer

By the end of this page, you will understand why some Ruby gems need compilation, what Ruby header files are, why native extension builds fail, and how to fix the problem by installing the correct development packages on Linux.

Concept

Some Ruby gems are written entirely in Ruby, but others include native extensions written in C. These extensions must be compiled during installation.

The mysql gem is one of those gems. When you run:

gem install mysql

RubyGems tries to:

  1. run extconf.rb
  2. generate a Makefile
  3. compile C code
  4. link it against Ruby and sometimes external libraries such as MySQL

To compile a native extension, the system needs development files, not just the Ruby interpreter.

These development files usually include:

  • Ruby header files such as ruby.h
  • compiler tools such as gcc and make
  • library development packages such as MySQL client headers

In this case, the key error is:

mkmf.rb can't find header files for ruby at /usr/lib/ruby/ruby.h

That means Ruby itself is installed, but the Ruby development headers are missing. On Linux distributions, runtime packages and development packages are often split apart.

So the issue is not that Ruby is absent. The issue is that the gem needs files used for compilation, and those files are not currently installed.

This matters in real programming because many gems depend on external libraries or native code for:

  • database drivers
  • image processing
  • JSON performance
  • cryptography
  • networking

Whenever a gem has to compile code, you need the matching development environment.

Mental Model

Think of installing a native gem like assembling a machine from parts.

  • The Ruby interpreter is the finished machine already running.
  • The gem with native extensions is a custom attachment you want to add.
  • The header files like ruby.h are the blueprints and connector specifications.

If you only have the machine but not the blueprints, the builder cannot attach the new part correctly.

So the error is basically saying:

I can see Ruby is installed, but I do not have the files that describe how to build something that connects to Ruby.

On Linux, those blueprint files usually come from packages named like:

  • ruby-devel
  • mysql-devel
  • build-essential or compiler tools
Take Quiz

Syntax and Examples

A native gem installation usually looks simple:

gem install mysql

But behind the scenes, it may require development packages.

Typical fix on Fedora

For Fedora or similar RPM-based systems, you usually need:

sudo yum install ruby-devel gcc make mysql-devel

Then try the gem install again:

gem install mysql

Why this works

  • ruby-devel provides ruby.h and other Ruby headers
  • gcc compiles C source files
  • make runs the build process
  • mysql-devel provides MySQL client headers and libraries

Example of checking whether the header exists

ls /usr/include/ruby* 

Or on some systems:

rpm -ql ruby-devel

This helps confirm whether the Ruby development package is installed.

Another example with a different gem

Many gems behave the same way:

gem install pg

If PostgreSQL development headers are missing, installation will fail in a similar way. The pattern is the same: install the development package, then retry.

Step by Step Execution

Consider this command:

gem install mysql

Here is what happens step by step:

  1. RubyGems downloads the mysql gem.
  2. It detects that the gem contains native C extensions.
  3. It runs a setup script, often named extconf.rb.
  4. extconf.rb uses Ruby's mkmf library to inspect your system.
  5. mkmf looks for required files such as:
    • Ruby headers like ruby.h
    • MySQL headers
    • compiler tools
  6. In your case, it fails immediately because it cannot find ruby.h.
  7. Since it cannot generate a valid build configuration, compilation stops.
  8. RubyGems reports Failed to build gem native extension.

Small trace example

Suppose the installer needs this file:

/usr/include/ruby-1.8/ruby.h

If the file is missing:

  • extconf.rb cannot continue
  • no valid Makefile is produced
  • the C extension is never compiled
  • the gem install fails

Important detail

The first useful error is often not the final Failed to build gem native extension line. The real clue is usually a line above it, such as:

mkmf.rb can't find header files for ruby

When debugging gem installs, always read the first specific missing dependency message.

Real World Use Cases

Native extensions appear often in real Ruby projects.

Database adapters

Gems such as MySQL, PostgreSQL, and SQLite adapters often compile native code to communicate efficiently with database libraries.

Performance-sensitive libraries

Some gems use C code for speed, especially when pure Ruby would be too slow.

System integration

Libraries that interact with operating system features, networking, image libraries, or encryption tools often require native compilation.

Legacy projects

Older Ruby applications, especially on older Linux systems, often depend on gems like mysql, which need system packages and headers to build.

CI and deployment

In CI pipelines or production servers, native gems may fail if the machine has runtime packages installed but not development packages. This is a common setup issue.

Take Quiz

Real Codebase Usage

In real projects, developers usually handle native gem dependencies in a few common ways.

Document system dependencies

Projects often include setup steps such as:

yum install ruby-devel mysql-devel gcc make

This is usually written in:

  • a README
  • a Dockerfile
  • provisioning scripts
  • CI configuration

Use dependency installation scripts

Teams often automate setup so new developers do not have to guess which packages are required.

Example:

sudo yum install -y ruby-devel mysql-devel gcc make
bundle install

Read build logs

When installation fails, developers check files like:

gem_make.out
mkmf.log

These logs often show the real missing dependency.

Prefer maintained gems

In modern Ruby projects, developers often use newer, maintained adapters instead of older gems when possible. But the same native-extension principle still applies.

Match runtime and development packages

A common pattern is making sure the interpreter version matches the development package version. For example, Ruby 1.8 runtime should have the matching ruby-devel package, not a different Ruby version.

Common Mistakes

1. Thinking Ruby itself is enough

Beginners often assume that if ruby -v works, gem compilation should also work.

That is not always true.

  • ruby gives you the interpreter
  • ruby-devel gives you header files for compiling extensions

2. Ignoring the specific missing file

This error:

Failed to build gem native extension

is generic.

The useful part is:

can't find header files for ruby

Always look for the first detailed error.

3. Installing only the database server

Having MySQL Server installed does not always mean you have the client development files.

You may still need:

sudo yum install mysql-devel

4. Missing compiler tools

Even with the correct headers, the build can fail if tools are missing.

You may need:

sudo yum install gcc make

5. Confusing runtime packages with development packages

Broken assumption:

# Ruby exists, so compilation should work
ruby -v

Correct approach:

sudo yum install ruby-devel

6. Using old gems without checking compatibility

Some older gems work differently across Ruby versions and OS versions. If a gem is old, check whether:

  • it is still maintained
  • there is a newer replacement
  • your Ruby version is compatible

Comparisons

ConceptWhat it providesNeeded to run Ruby code?Needed to build native gems?
rubyRuby interpreterYesYes
ruby-develRuby headers like ruby.hNoYes
mysql-serverDatabase server processNoNo
mysql client librariesDatabase client supportSometimesOften
mysql-develMySQL headers and linkable libsNoYes
gcc / makeBuild toolsNoYes

Pure Ruby gem vs native gem

TypeNeeds compilation?Needs headers/tools?Example
Pure Ruby gemNoNomany utility gems
Native extension gemYesYesmysql, pg, some image gems

Generic error vs useful error

MessageMeaning
Failed to build gem native extensionSomething in compilation failed
can't find header files for rubyRuby development package is missing
checking for mysql_query()... noMySQL development files may be missing
Take Quiz

Cheat Sheet

# Install Ruby development headers on Fedora
sudo yum install ruby-devel

# Install common build tools
sudo yum install gcc make

# Install MySQL development files
sudo yum install mysql-devel

# Retry gem installation
gem install mysql

Key idea

If a gem builds native extensions, you often need:

  • language development headers
  • compiler tools
  • library development packages

Error clues

  • ruby.h missing -> install ruby-devel
  • MySQL headers missing -> install mysql-devel
  • compiler not found -> install gcc and make

Debugging files

Look at:

  • gem_make.out
  • mkmf.log

Rule of thumb

If a gem compiles C code, runtime packages alone are usually not enough.

FAQ

Why does gem install mysql try to compile code?

Because the mysql gem includes a native extension written in C, which must be built on your machine.

What is ruby.h?

ruby.h is a Ruby header file used when compiling native extensions that connect C code to Ruby.

Why is Ruby installed but ruby.h missing?

On Linux, runtime and development files are often packaged separately. You may have ruby installed but not ruby-devel.

Is installing MySQL Server enough for the mysql gem?

No. You may also need MySQL development files such as mysql-devel so the gem can compile and link correctly.

What package should I install on Fedora for this specific error?

Usually ruby-devel is the direct fix for the missing ruby.h error. You may also need gcc, make, and mysql-devel.

Where can I find more details about the build failure?

Check the generated log files, especially gem_make.out and often mkmf.log inside the gem extension directory.

Does running the command as root fix missing headers?

No. Permissions and missing development files are different problems. Root access does not provide header files.

Are native extension errors common with Ruby gems?

Yes. They are common when working with database adapters, image libraries, cryptography gems, and system-level integrations.

Take Quiz

Mini Project

Description

Create a small setup checklist for installing a Ruby project that depends on a native MySQL gem. This project helps you practice identifying runtime dependencies versus development dependencies and writing repeatable setup steps for Linux environments.

Goal

Write and test a simple installation script or checklist that prepares a Fedora machine to compile and install a native Ruby MySQL gem successfully.

Requirements

[ "Install the Ruby development package required for ruby.h.", "Install the compiler tools needed to build native extensions.", "Install the MySQL development package required by the gem.", "Run the gem installation command after dependencies are installed.", "Verify that the gem installation completes without the missing-header error." ]

Take Quiz

Keep learning

Related questions

View more