{"record":{"id":"8860fca4afefd9e9","repo":"github/copilot-sdk","slug":"not-an-elf-executable","errorCode":null,"errorMessage":"Not an ELF executable","messagePattern":"Not an ELF executable","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/PlatformDetector.java","lineNumber":170,"sourceCode":"        if (classifier == null || !SUPPORTED_CLASSIFIERS.contains(classifier)) {\n            throw new IllegalStateException(\n                    \"Unsupported platform tuple: os=\" + os + \", arch=\" + arch + \", libc=\" + classifierLibc);\n        }\n        return classifier;\n    }\n\n    static Set<String> supportedClassifiers() {\n        return SUPPORTED_CLASSIFIERS;\n    }\n\n    private static String readElfPtInterp(byte[] probe) throws IOException {\n        int size = probe.length;\n        if (size < 64) {\n            throw new IOException(\"ELF probe too small: \" + size + \" bytes\");\n        }\n        if ((probe[0] & 0xFF) != ELF_MAGIC_0 || (probe[1] & 0xFF) != ELF_MAGIC_1 || (probe[2] & 0xFF) != ELF_MAGIC_2\n                || (probe[3] & 0xFF) != ELF_MAGIC_3) {\n            throw new IOException(\"Not an ELF executable\");\n        }\n\n        int elfClass = probe[4] & 0xFF;\n        int elfData = probe[5] & 0xFF;\n        if (elfData != ELF_DATA_LITTLE_ENDIAN && elfData != ELF_DATA_BIG_ENDIAN) {\n            throw new IOException(\"Unsupported ELF data encoding: \" + elfData);\n        }\n        boolean littleEndian = elfData == ELF_DATA_LITTLE_ENDIAN;\n\n        long phoff;\n        int phentsize;\n        int phnum;\n        int minimumPhentsize;\n        if (elfClass == ELF_CLASS_64) {\n            phoff = readUInt64(probe, 32, littleEndian);\n            phentsize = readUInt16(probe, 54, littleEndian);\n            phnum = readUInt16(probe, 56, littleEndian);\n            minimumPhentsize = ELF64_PROGRAM_HEADER_SIZE;","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/PlatformDetector.java#L152-L188","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nString interp = readElfPtInterp(probe); // probe from wrapper.sh\n// after\nbyte[] probe = readHead(binaryPath);\nif ((probe[0] & 0xFF) != 0x7F || probe[1] != 'E' || probe[2] != 'L' || probe[3] != 'F') {\n    throw new IOException(binaryPath + \" is not an ELF binary; path=\" + binaryPath);\n}\nString interp = readElfPtInterp(probe);","handlingStrategy":"try-catch","validationCode":"byte[] magic = new byte[4];\ntry (InputStream in = Files.newInputStream(path)) { in.readNBytes(magic, 0, 4); }\nif (magic[0] != 0x7F || magic[1] != 'E' || magic[2] != 'L' || magic[3] != 'F') {\n    throw new IOException(path + \" is not an ELF binary\");\n}","typeGuard":"static boolean isElf(Path p) throws IOException {\n    byte[] m = new byte[4];\n    try (InputStream in = Files.newInputStream(p)) { return in.readNBytes(m, 0, 4) == 4\n        && m[0] == 0x7F && m[1] == 'E' && m[2] == 'L' && m[3] == 'F'; }\n}","tryCatchPattern":"try {\n    String interp = resolveInterpreter(binaryPath);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"Not an ELF\")) {\n        throw new IllegalStateException(binaryPath + \" is not an ELF executable (wrong platform or wrapper script)\", e);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["elf","binary-parsing","file-format","java"],"backgroundTag":"invalid-argument-format","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}