{"record":{"id":"25936302561f4b7c","repo":"github/copilot-sdk","slug":"elf-pt-interp-segment-not-found","errorCode":null,"errorMessage":"ELF PT_INTERP segment not found","messagePattern":"ELF PT_INTERP segment not found","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/ffi/PlatformDetector.java","lineNumber":250,"sourceCode":"            }\n\n            int start = (int) pOffset;\n            int end = start + (int) pFileSize;\n            if (end > size) {\n                throw new IOException(\"PT_INTERP extends past probe window; increase probe size\");\n            }\n\n            int nulIndex = start;\n            while (nulIndex < end && probe[nulIndex] != 0) {\n                nulIndex++;\n            }\n            if (nulIndex == start) {\n                throw new IOException(\"Empty PT_INTERP segment\");\n            }\n            return new String(probe, start, nulIndex - start, StandardCharsets.UTF_8);\n        }\n\n        throw new IOException(\"ELF PT_INTERP segment not found\");\n    }\n\n    private static byte[] readPrefix(Path path, int maxBytes) throws IOException {\n        byte[] buffer = new byte[maxBytes];\n        int total = 0;\n        try (InputStream in = Files.newInputStream(path)) {\n            while (total < maxBytes) {\n                int read = in.read(buffer, total, maxBytes - total);\n                if (read < 0) {\n                    break;\n                }\n                total += read;\n            }\n        }\n        byte[] resized = new byte[total];\n        System.arraycopy(buffer, 0, resized, 0, total);\n        return resized;\n    }","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/ffi/PlatformDetector.java#L232-L268","documentation":"Thrown by readElfPtInterp when parsing an ELF binary that contains no PT_INTERP program header, i.e. the file has no embedded dynamic loader path (e.g. a statically linked executable or not a dynamically linked ELF at all). The library uses the PT_INTERP segment to locate the interpreter (e.g. /lib64/ld-linux-x86-64.so.2) when detecting the target platform. If the whole segment table is scanned without finding PT_INTERP, it reports the segment as missing.","triggerScenarios":"Calling PlatformDetector's interpreter detection (via readElfPtInterp) on a binary whose ELF program header table contains no PT_INTERP entry — statically linked executables, pure Go/Rust static binaries, musl-static builds, or corrupt/truncated ELF files.","commonSituations":"Pointing the FFI platform detector at a statically linked CLI binary; scanning a container image binary built with CGO_ENABLED=0; inspecting a non-ELF file that passed a partial magic check; inspecting stripped or corrupted binaries copied out of archives.","solutions":["Verify the binary is dynamically linked: run `file <binary>` or `readelf -l <binary>` and confirm a PT_INTERP (INTERP) segment exists.","If the binary is intentionally static, don't rely on PT_INTERP for platform detection — pass the platform explicitly or use an OS/arch probe (e.g. uname) instead.","If you expected a dynamic binary, rebuild with dynamic linking (remove -static / set CGO_ENABLED=1 for Go).","Check the file isn't truncated or corrupted; re-download or re-copy the artifact and compare its checksum."],"exampleFix":"// before\nString interp = PlatformDetector.readElfPtInterp(staticBinary);\n\n// after\nif (PlatformDetector.hasElfInterp(staticBinary)) {\n    String interp = PlatformDetector.readElfPtInterp(staticBinary);\n} else {\n    Platform = detectViaUname(); // static binary: no PT_INTERP to read\n}","handlingStrategy":"fallback","validationCode":"byte[] prefix = readPrefix(binary, 64);\nboolean dynamic = false;\n// scan ELF program headers or simply:\nString out = new String(Files.readAllBytes(Path.of(\"/proc/self/exe\"))); // not needed; use readelf-like check\n// simple guard:\n// if (!hasInterpSegment(elf)) fall back to uname-based detection","typeGuard":"static boolean isDynamicallyLinked(Path elf) throws IOException {\n    try (RandomAccessFile raf = new RandomAccessFile(elf.toFile(), \"r\")) {\n        byte[] head = new byte[64];\n        raf.readFully(head);\n        return new String(head, 0, 4, StandardCharsets.US_ASCII).equals(\"\\u007fELF\");\n        // treat absence of PT_INTERP (caught IOException) as static\n    }\n}","tryCatchPattern":"try {\n    String interp = readElfPtInterp(binary);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"PT_INTERP segment not found\")) {\n        platform = detectViaUname(); // static binary fallback\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check binaries with `file`/`readelf -l` before relying on interpreter-based detection","Expect static binaries (Go, Rust, musl) to lack PT_INTERP and provide a platform override","Verify artifact checksums to rule out truncated files","Test platform detection on both static and dynamic builds in CI"],"tags":["java","elf","ffi","platform-detection"],"backgroundTag":"unsupported-platform","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}