tursodatabase/turso · error · SystemExit
{path} is not an ELF file
Error message
{path} is not an ELF file What it means
dynsym_names() reads the file and validates the ELF magic bytes (\x7fELF) before parsing. If the first 4 bytes do not match, the path does not point to an ELF binary (it may be a text file, Mach-O/PE binary, script, or empty file). The script exits with this message and status 1.
Source
Thrown at bindings/dotnet/scripts/check_elf_dynsym_exports.py:94
name: int,
typ: int,
flags: int,
offset: int,
size: int,
link: int,
info: int,
align: int,
entsize: int,
) -> bytes:
return struct.pack(
"<IIQQQQIIQQ", name, typ, flags, 0, offset, size, link, info, align, entsize
)
def dynsym_names(path: Path) -> set[str]:
data = path.read_bytes()
if data[:4] != b"\x7fELF":
raise SystemExit(f"{path} is not an ELF file")
layout = elf_layout(data, path)
dynsym = find_dynsym(data, layout, path)
return names_from_dynsym(data, layout, dynsym)
def elf_layout(data: bytes, path: Path) -> dict:
endian = "<" if data[5] == 1 else ">"
elf_class = data[4]
if elf_class == 2:
return {
"endian": endian,
"section_header_offset": struct.unpack_from(endian + "Q", data, 40)[0],
"section_header_size": struct.unpack_from(endian + "H", data, 58)[0],
"section_count": struct.unpack_from(endian + "H", data, 60)[0],
"string_table_index": struct.unpack_from(endian + "H", data, 62)[0],
"section_format": endian + "IIQQQQIIQQ",
"symbol_format": endian + "IBBHQQ",View on GitHub (pinned to 492c4a71cd)
Solutions
- Verify the file is the Linux ELF artifact: `file <path>` should report 'ELF 64-bit'
- Pass the correct .so path for the target platform; use platform-specific CI steps for .dll/.dylib
- Check the build actually succeeded and produced a real binary, not an empty/partial file
- If the file is genuinely an ELF but starts differently, check for corruption or accidental text wrapping
Example fix
// before check_elf_dynsym_exports.py build/libturso.dylib turso_sync_database_new // after check_elf_dynsym_exports.py build/libturso.so turso_sync_database_new
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
path = Path(elf_path)
if not path.exists() or path.read_bytes()[:4] != b"\x7fELF":
raise ValueError(f"{path} is not an ELF file") Type guard
def is_elf(path) -> bool:
try:
return Path(path).read_bytes()[:4] == b"\x7fELF"
except OSError:
return False Try / catch
try:
subprocess.run(["check_elf_dynsym_exports.py", elf, *symbols], check=True)
except SystemExit:
# or CalledProcessError when run via subprocess
# verify with `file <elf>` that the artifact is a Linux ELF .so
... Prevention
- Validate the artifact type with `file <path>` before running the checker
- Use platform-specific CI jobs so only ELF artifacts hit this script
- Ensure the build completed before checking; a failed build can leave empty files
When it happens
Trigger: Calling missing_exports()/dynsym_names() on a path whose contents do not start with b'\x7fELF' — e.g. checking a .dll, .dylib, or an archive file instead of an ELF .so.
Common situations: CI passes the wrong platform artifact (Windows .dll or macOS .dylib on a Linux check step), the path points to a stub or a text file, the build failed and a placeholder file exists, or a glob picked up non-ELF files.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- {path} has unsupported ELF class {elf_class}
- {path} has no .dynsym section
- pyturso's SQLAlchemy dialects require SQLAlchemy >= 2.0.45 (
- Cannot get raw connection from SQLAlchemy connection
- Expected turso.sync.ConnectionSync, got {type(dbapi_conn).__
AI-assisted analysis of tursodatabase/turso@492c4a71cd (2026-09-13).
Data as JSON: /api/errors/de945381e186ab14.
Report an issue: GitHub.