github/copilot-sdk · error · IOException

ELF PT_INTERP segment not found

Error message

ELF PT_INTERP segment not found

What it means

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.

Solutions

  1. Verify the binary is dynamically linked: run `file <binary>` or `readelf -l <binary>` and confirm a PT_INTERP (INTERP) segment exists.
  2. 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.
  3. If you expected a dynamic binary, rebuild with dynamic linking (remove -static / set CGO_ENABLED=1 for Go).
  4. Check the file isn't truncated or corrupted; re-download or re-copy the artifact and compare its checksum.

Example fix

// before
String interp = PlatformDetector.readElfPtInterp(staticBinary);

// after
if (PlatformDetector.hasElfInterp(staticBinary)) {
    String interp = PlatformDetector.readElfPtInterp(staticBinary);
} else {
    Platform = detectViaUname(); // static binary: no PT_INTERP to read
}
Defensive patterns

Strategy: fallback

Validate before calling

byte[] prefix = readPrefix(binary, 64);
boolean dynamic = false;
// scan ELF program headers or simply:
String out = new String(Files.readAllBytes(Path.of("/proc/self/exe"))); // not needed; use readelf-like check
// simple guard:
// if (!hasInterpSegment(elf)) fall back to uname-based detection

Type guard

static boolean isDynamicallyLinked(Path elf) throws IOException {
    try (RandomAccessFile raf = new RandomAccessFile(elf.toFile(), "r")) {
        byte[] head = new byte[64];
        raf.readFully(head);
        return new String(head, 0, 4, StandardCharsets.US_ASCII).equals("\u007fELF");
        // treat absence of PT_INTERP (caught IOException) as static
    }
}

Try / catch

try {
    String interp = readElfPtInterp(binary);
} catch (IOException e) {
    if (e.getMessage().contains("PT_INTERP segment not found")) {
        platform = detectViaUname(); // static binary fallback
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/25936302561f4b7c. Report an issue: GitHub.

Appendix: source

Thrown at java/sdk/src/main/java/com/github/copilot/ffi/PlatformDetector.java:250

            }

            int start = (int) pOffset;
            int end = start + (int) pFileSize;
            if (end > size) {
                throw new IOException("PT_INTERP extends past probe window; increase probe size");
            }

            int nulIndex = start;
            while (nulIndex < end && probe[nulIndex] != 0) {
                nulIndex++;
            }
            if (nulIndex == start) {
                throw new IOException("Empty PT_INTERP segment");
            }
            return new String(probe, start, nulIndex - start, StandardCharsets.UTF_8);
        }

        throw new IOException("ELF PT_INTERP segment not found");
    }

    private static byte[] readPrefix(Path path, int maxBytes) throws IOException {
        byte[] buffer = new byte[maxBytes];
        int total = 0;
        try (InputStream in = Files.newInputStream(path)) {
            while (total < maxBytes) {
                int read = in.read(buffer, total, maxBytes - total);
                if (read < 0) {
                    break;
                }
                total += read;
            }
        }
        byte[] resized = new byte[total];
        System.arraycopy(buffer, 0, resized, 0, total);
        return resized;
    }

View on GitHub (pinned to cd8cf15dc3)