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
- Increase the probe size so it covers the program header table (e.g. 4096 bytes or more, or read the first min(fileSize, 64KiB)).
- 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.
- Re-download/reinstall the binary and check its checksum.
- 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
- Read a large head slice (>= 64KiB) or the whole file instead of tiny fixed probes.
- Validate binaries with `readelf -l <path>` during packaging.
- Check file completeness (size + checksum) after download.
- Start probes at file offset 0 of the real file.
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
- ELF probe too small: + size + bytes
- PT_INTERP extends past probe window; increase probe size
- Not an ELF executable
- Unsupported ELF data encoding: + elfData
- Unsupported ELF class: + elfClass
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)