github/copilot-sdk · error · IOException

Program header table offset outside probe window: + phoff

Error message

Program header table offset outside probe window: + phoff

What it means

The parsed e_phoff (program header table offset) must fall inside the probe bytes actually read from the file. If it is negative or beyond the probe window, the ELF header is corrupt or the probe is truncated relative to what the header claims, so parsing cannot continue and an IOException is thrown.

Solutions

  1. Increase the probe size so it covers the program header table (e.g. 4096 bytes or more, or read the first min(fileSize, 64KiB)).
  2. Verify the binary with `readelf -l <path>` — if readelf shows a sane program header table, your probe is too small; if not, the file is corrupt.
  3. Re-download/reinstall the binary and check its checksum.
  4. Confirm the probe was read from offset 0 of the actual file (not a re-based slice).

Example fix

// before
byte[] probe = new byte[256];
readFully(path, probe);
String interp = readElfPtInterp(probe);
// after
byte[] probe = Files.readAllBytes(path); // or a 64KiB head-read
String interp = readElfPtInterp(probe);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the probe covers the program header table
long fileSize = Files.size(path);
byte[] probe = readHead(path, (int) Math.min(fileSize, 65536));
// probe.length must exceed any plausible e_phoff + phentsize*phnum

Try / catch

try {
    String interp = readElfPtInterp(probe);
} catch (IOException e) {
    if (e.getMessage().startsWith("Program header table offset outside")) {
        probe = Files.readAllBytes(path); // retry with the full file
        interp = readElfPtInterp(probe);
    } else throw e;
}

Prevention

When it happens

Trigger: e_phoff parsed from the header exceeds the probe length (probe smaller than the header promises, e.g. a truncated read of a large binary) or the header itself is corrupt, yielding a negative/absurd offset.

Common situations: Reading only the first N bytes of a large statically linked binary whose program header table sits beyond the probe; corrupted binaries with garbage e_phoff; partial downloads.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


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

Appendix: source

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

        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;
        } else if (elfClass == ELF_CLASS_32) {
            phoff = readUInt32(probe, 28, littleEndian);
            phentsize = readUInt16(probe, 42, littleEndian);
            phnum = readUInt16(probe, 44, littleEndian);
            minimumPhentsize = ELF32_PROGRAM_HEADER_SIZE;
        } else {
            throw new IOException("Unsupported ELF class: " + elfClass);
        }

        if (phoff < 0 || phoff >= size) {
            throw new IOException("Program header table offset outside probe window: " + phoff);
        }
        if (phentsize < minimumPhentsize || phnum <= 0) {
            throw new IOException("Invalid ELF program header metadata: phentsize=" + phentsize + ", phnum=" + phnum);
        }

        for (int i = 0; i < phnum; i++) {
            long baseLong = phoff + ((long) i * phentsize);
            if (baseLong < 0 || baseLong > Integer.MAX_VALUE) {
                break;
            }
            int base = (int) baseLong;
            if (base + phentsize > size) {
                break;
            }

            long pType = readUInt32(probe, base, littleEndian);
            if (pType != PT_INTERP) {
                continue;

View on GitHub (pinned to cd8cf15dc3)