cannot enable executable stack as shared object requires: Invalid argument (fix)
ImportError: libtorch_cpu.so: cannot enable executable stack as shared object requires: Invalid argument appears when an old compiled library is loaded on glibc 2.41 or newer. We reproduced it with torch 1.10.2 on Debian 13 and tested three fixes, including one that needs no root.
1. The error
import torch
print("torch", torch.__version__)
print(torch.ones(2) + 1)
torch 1.10.2+cpu on Debian 13 (glibc 2.41):
.../site-packages/torch/torch_version.py:3: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
from pkg_resources import packaging # type: ignore[attr-defined]
Traceback (most recent call last):
File "b1.py", line 1, in <module>
import torch
File ".../site-packages/torch/__init__.py", line 197, in <module>
from torch._C import * # noqa: F403
ImportError: libtorch_cpu.so: cannot enable executable stack as shared object requires: Invalid argument
The pkg_resources warning on top is unrelated (old torch imports it; with setuptools 81+ removed it becomes No module named pkg_resources). The ImportError is the real failure: the shared library is marked as needing an executable stack (its PT_GNU_STACK program header has the execute flag), and glibc 2.41 no longer lets dlopen turn on an executable stack for a library loaded at runtime. Python extension modules are always loaded with dlopen, so any old wheel built with that flag fails this way on new distros (Debian 13, Fedora 42, Arch, Ubuntu 25.04+ ship glibc 2.41 or newer).
2. Find which libraries carry the flag
The error names one library, but there can be several. This stdlib-only script reads each .so file's program headers:
import glob, os, struct, sys
PT_GNU_STACK = 0x6474E551
PF_X = 1
def needs_execstack(path):
with open(path, "rb") as f:
hdr = f.read(64)
if hdr[:4] != b"\x7fELF" or hdr[4] != 2: # 64-bit ELF only
return None
phoff, = struct.unpack_from("<Q", hdr, 0x20)
phentsize, phnum = struct.unpack_from("<HH", hdr, 0x36)
for i in range(phnum):
f.seek(phoff + i * phentsize)
p_type, p_flags = struct.unpack("<II", f.read(8))
if p_type == PT_GNU_STACK:
return bool(p_flags & PF_X)
return None
root = sys.argv[1]
for so in sorted(glob.glob(os.path.join(root, "**", "*.so*"), recursive=True)):
if needs_execstack(so):
print("needs executable stack:", os.path.relpath(so, root))
print("scan done")
python b2.py .../site-packages/torch on torch 1.10.2:
needs executable stack: lib/libtorch_cpu.so
scan done
Same scan on torch 2.9.0+cpu:
scan done
(readelf -lW file.so | grep GNU_STACK shows the same thing: RWE means executable stack, RW means not.)
3. Fix A: upgrade the package
Current releases are built without the flag (torch 2.9.0 has none, above), so if you can move to a newer version, do that. If you have to keep the old one, use B or C.
4. Fix B: clear the flag with patchelf (no root)
pip install patchelf gives you the binary inside the venv. Then, for each library the scan listed:
SP=$(python -c "import sysconfig; print(sysconfig.get_paths()['purelib'])")
patchelf --version
patchelf --clear-execstack "$SP/torch/lib/libtorch_cpu.so"
echo "patched"
patchelf 0.19.1
patched
Scan and import again:
scan done
.../site-packages/torch/torch_version.py:3: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
from pkg_resources import packaging # type: ignore[attr-defined]
torch 1.10.2+cpu
tensor([2., 2.])
The flag is almost always a build leftover (an assembly file without a .note.GNU-stack section), not something the code needs, which is why clearing it works. Reinstalling the package brings the flag back, so re-run the patch after every reinstall.
5. Fix C: the glibc tunable (no file changes)
With the original, unpatched library:
GLIBC_TUNABLES=glibc.rtld.execstack=2 python b1.py
.../site-packages/torch/torch_version.py:3: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
from pkg_resources import packaging # type: ignore[attr-defined]
torch 1.10.2+cpu
tensor([2., 2.])
This worked on Debian's glibc 2.41. It allows an executable stack for the whole process, which is the protection glibc just turned on, so prefer A or B and keep C for a quick check.
Related: onnxruntime version of this error · No module named pkg_resources · libtorchaudio.so undefined symbol · operator torchvision::nms does not exist
Frequently asked questions
Why did this start after an OS upgrade?
glibc 2.41 stopped letting dlopen enable an executable stack. Libraries marked as needing one now fail to load instead of silently weakening the process.
Is patchelf --clear-execstack safe?
For prebuilt wheels like torch the flag is a build leftover, and the library worked normally after clearing it here. Code that really runs on the stack would crash, so test after patching.
Does it only affect torch?
No. Any old .so with an executable-stack flag fails the same way; the scan script finds them in any package directory.
Written with AI assistance. Measured on 2026-10-24 on Debian 13 (glibc 2.41-12+deb13u4): torch 1.10.2+cpu (CPython 3.9), torch 2.9.0+cpu (CPython 3.11.17), patchelf 0.19.1. Output pasted unedited except shortened paths. PlainTables is our extension; patchelf and torch are free.