github/copilot-sdk · error · IOException
Not an ELF executable
Error message
Not an ELF executable
What it means
readElfPtInterp checks the first 4 bytes of the probe against the ELF magic number (0x7F 'E' 'L' 'F'). If they do not match, the file is not an ELF executable and PT_INTERP parsing cannot proceed, so an IOException is thrown. This guards against parsing arbitrary non-ELF files.
Solutions
- Confirm the target file is actually ELF: run file <path>; expect 'ELF 64-bit LSB ...'.
- Only invoke ELF parsing on Linux targets; use the platform-appropriate path (Mach-O/PE) on macOS/Windows.
- Re-download or reinstall the binary — an HTML error page or truncated file has no ELF magic.
- Check that symlinks resolve to the real binary and not a script.
Example fix
// before
String interp = readElfPtInterp(probe); // probe from wrapper.sh
// after
byte[] probe = readHead(binaryPath);
if ((probe[0] & 0xFF) != 0x7F || probe[1] != 'E' || probe[2] != 'L' || probe[3] != 'F') {
throw new IOException(binaryPath + " is not an ELF binary; path=" + binaryPath);
}
String interp = readElfPtInterp(probe); Defensive patterns
Strategy: try-catch
Validate before calling
byte[] magic = new byte[4];
try (InputStream in = Files.newInputStream(path)) { in.readNBytes(magic, 0, 4); }
if (magic[0] != 0x7F || magic[1] != 'E' || magic[2] != 'L' || magic[3] != 'F') {
throw new IOException(path + " is not an ELF binary");
} Type guard
static boolean isElf(Path p) throws IOException {
byte[] m = new byte[4];
try (InputStream in = Files.newInputStream(p)) { return in.readNBytes(m, 0, 4) == 4
&& m[0] == 0x7F && m[1] == 'E' && m[2] == 'L' && m[3] == 'F'; }
} Try / catch
try {
String interp = resolveInterpreter(binaryPath);
} catch (IOException e) {
if (e.getMessage().contains("Not an ELF")) {
throw new IllegalStateException(binaryPath + " is not an ELF executable (wrong platform or wrapper script)", e);
}
throw e;
} Prevention
- Only run ELF parsing on Linux; branch to Mach-O/PE logic on macOS/Windows.
- Validate downloads with checksums to catch HTML-error-page or truncated payloads.
- Run `file <path>` in CI sanity checks before shipping binaries.
- Resolve symlinks to ensure you inspect the real binary, not a script.
When it happens
Trigger: The probe comes from a file that is not an ELF binary: a Mach-O binary (macOS), a PE binary (Windows), a shell script, a text file, or a truncated/corrupt download whose magic bytes were lost.
Common situations: Running interpreter resolution on macOS or Windows binaries when the code path assumes ELF; pointing the resolver at a wrapper script; downloading a binary over a connection that served an HTML error page instead of the file.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- ELF probe too small: + size + bytes
- Unsupported ELF data encoding: + elfData
- Unsupported ELF class: + elfClass
- Program header table offset outside probe window: + phoff
- Invalid ELF program header metadata: phentsize= + phentsize…
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/8860fca4afefd9e9.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/ffi/PlatformDetector.java:170
if (classifier == null || !SUPPORTED_CLASSIFIERS.contains(classifier)) {
throw new IllegalStateException(
"Unsupported platform tuple: os=" + os + ", arch=" + arch + ", libc=" + classifierLibc);
}
return classifier;
}
static Set<String> supportedClassifiers() {
return SUPPORTED_CLASSIFIERS;
}
private static String readElfPtInterp(byte[] probe) throws IOException {
int size = probe.length;
if (size < 64) {
throw new IOException("ELF probe too small: " + size + " bytes");
}
if ((probe[0] & 0xFF) != ELF_MAGIC_0 || (probe[1] & 0xFF) != ELF_MAGIC_1 || (probe[2] & 0xFF) != ELF_MAGIC_2
|| (probe[3] & 0xFF) != ELF_MAGIC_3) {
throw new IOException("Not an ELF executable");
}
int elfClass = probe[4] & 0xFF;
int elfData = probe[5] & 0xFF;
if (elfData != ELF_DATA_LITTLE_ENDIAN && elfData != ELF_DATA_BIG_ENDIAN) {
throw new IOException("Unsupported ELF data encoding: " + elfData);
}
boolean littleEndian = elfData == ELF_DATA_LITTLE_ENDIAN;
long phoff;
int phentsize;
int phnum;
int minimumPhentsize;
if (elfClass == ELF_CLASS_64) {
phoff = readUInt64(probe, 32, littleEndian);
phentsize = readUInt16(probe, 54, littleEndian);
phnum = readUInt16(probe, 56, littleEndian);
minimumPhentsize = ELF64_PROGRAM_HEADER_SIZE;View on GitHub (pinned to cd8cf15dc3)