guides / glibcxx-version-not-found troubleshootingupdated 2026-10-25 readelf -h ./app

version `GLIBCXX_3.4.29' not found — the libstdc++ counterpart

2026-10-25 By luckyray Debian 12 · Ubuntu 24.04 · Alpine 3.20
$ ./tool
./tool: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found
         (required by ./tool)

This looks like the GLIBC symbol-version error and behaves the same way, but the provider is different: GLIBCXX_* symbols come from libstdc++, the GCC C++ runtime, not from libc. That matters because the fixes are not interchangeable.

Reading the version number

GLIBCXX_3.4.29 encodes a GCC release: the 3.4 is the historical ABI baseline and the last component tracks GCC versions.

GLIBCXX_Introduced in GCC
3.4.194.8
3.4.225
3.4.258
3.4.289
3.4.2911
3.4.3012
3.4.3213
3.4.3314

So GLIBCXX_3.4.29 means “built with GCC 11 or newer”. A host whose libstdc++.so.6 came from GCC 9 tops out at 3.4.28 and cannot satisfy it.

Confirming the diagnosis

$ strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep -E '^GLIBCXX_3\.4\.[0-9]+$' | sort -V | tail -3
GLIBCXX_3.4.28
GLIBCXX_3.4.29
GLIBCXX_3.4.30

$ readelf -V ./tool | grep GLIBCXX | sort -u | tail -3
  0x0010:   Name: GLIBCXX_3.4.32  Flags: none  Version: 5

The first command lists what the host can provide; the second lists what the binary demands. Compare the maxima. CXXABI_1.3.x errors work exactly the same way and come from the same library.

The legitimate fixes

1. Build against an older toolchain. The correct answer for anything you ship. Building inside the oldest base image you support (or manylinux_2_28, or centos:7 for the truly conservative) caps the required GLIBCXX_ version at what that GCC emits.

2. Link the C++ runtime statically. For C++ this is often the cleanest option, and unlike libc it carries none of the NSS problems:

g++ -static-libstdc++ -static-libgcc -O2 -o tool tool.cpp

The result still links against glibc dynamically, so it inherits the GLIBC constraints — but the GLIBCXX/CXXABI requirement disappears because the runtime is inside the binary.

# check that it worked
readelf -d ./tool | grep -i stdc++      # expect no output

3. Ship the newer libstdc++.so.6 next to the binary.

patchelf --set-rpath '$ORIGIN/lib' ./tool

Unlike libc, replacing libstdc++ is comparatively safe: it is a normal shared library with a stable SONAME, it does not own the process’s memory allocator or its threading primitives, and a newer libstdc++ is backward compatible with older GLIBCXX_ symbols. This is exactly what many vendor tools do. Two caveats: it must still match the host’s libc.so.6 ABI, and if the process also loads another library that pulls in a different libstdc++, you get two copies in one process.

4. Use a newer base image. If the host is yours, upgrade it. The error is telling you the runtime is older than the compiler that produced the code.

What does not work

  • apt install libstdc++6 — usually already installed, and the package does not jump major GCC versions within a stable release.
  • Copying libstdc++.so.6 into /usr/lib — affects every C++ program on the host, including the package manager, and mixing it with the system libc is how you get GLIBC_2.38 not found in /usr/bin/apt.
  • Symlinking libstdc++.so.6 to a different major version — no such thing exists; the SONAME covers many GCC generations precisely so that a symlink is never needed.

Why this hits Python packages so often

A compiled Python extension (a wheel with .so files) is a C++ binary with the same version requirements. When a wheel built against manylinux_2_28 is installed on a host whose libstdc++ is from GCC 8, the import fails with GLIBCXX_3.4.29 and pip reports it as an ImportError — which sends people looking at Python versions instead of at the C++ runtime. pip debug --verbose and auditwheel show <wheel> are the tools that name the real constraint.

Related: wrong ELF class for the other “the library was found but rejected” failure, and checking hardening flags if you are reviewing the binary rather than fixing it.


Every command in this guide was run against the distribution named in the output. If your output differs, the mechanism section explains why — and the ELF Inspector shows the same fields without needing a shell.

Related

guides
  1. cannot execute binary file: Exec format error — causes and fixes Why Linux refuses to run a binary with Exec format error, how to confirm the cause in three commands, and the five fixes that actually apply.
  2. version `GLIBC_2.34' not found — why copying libc never works How glibc symbol versioning works, why a binary built on a newer distribution refuses to start on an older one, and the four legitimate fixes.
  3. wrong ELF class: ELFCLASS32 or ELFCLASS64 — what it means The 32-bit versus 64-bit mismatch that shows up at link time and at dlopen time, why it is not the same as Exec format error, and how to resolve it.