oracle/graal · error · IOException
Invalid replay string table index
Error message
Invalid replay string table index
What it means
IOException thrown by BinaryReplayCodec.ReadState.stringAt when a replay data stream references a string table index that is negative or >= the current table size. The binary replay format resolves strings by index into a table built incrementally during decoding; an out-of-range index means the stream is corrupt, truncated, or was written by an incompatible codec version.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/replaycomp/BinaryReplayCodec.java:252
private final class ReadState {
private final CompilationProxies.ProxyFactory proxyFactory;
private final ArrayList<String> stringTable = new ArrayList<>();
private final ArrayList<CompilationProxy.SymbolicMethod> methodTable = new ArrayList<>();
private final Object[] singletonProxies = new Object[registrations.length];
@SuppressWarnings("unchecked") private final EconomicMap<Integer, Object>[] instanceProxies = (EconomicMap<Integer, Object>[]) new EconomicMap<?, ?>[registrations.length];
private Architecture architecture = hostTarget.arch;
private ReadState(CompilationProxies.ProxyFactory proxyFactory) {
this.proxyFactory = proxyFactory;
stringTable.add(null);
}
private String stringAt(int index) throws IOException {
if (index < 0 || index >= stringTable.size()) {
throw new IOException("Invalid replay string table index " + index);
}
return stringTable.get(index);
}
private void defineString(int index, String value) throws IOException {
if (index != stringTable.size()) {
throw new IOException("Invalid replay string definition index " + index);
}
stringTable.add(value);
}
private CompilationProxy.SymbolicMethod methodAt(int index) throws IOException {
if (index < 0 || index >= methodTable.size()) {
throw new IOException("Invalid replay symbolic method index " + index);
}
return methodTable.get(index);
}
View on GitHub (pinned to a66e9ccd1d)
Solutions
- Regenerate the replay file with the exact compiler build used for replay.
- Verify the file is complete and unmodified (checksum/re-copy) and retry.
- If you must replay across versions, re-record profiles on the current build instead of reusing old ones.
Defensive patterns
Strategy: validation
Validate before calling
// Validate replay file before use: writer header/version must match reader build, and file must be complete
Path p = Paths.get(replayFile);
long expected = Long.parseLong(Files.readString(p.resolveSibling(p.getFileName() + ".size"))); // emitted by capture tooling
if (Files.size(p) != expected) {
throw new IOException("Replay file truncated: " + p);
} Try / catch
try {
replayCodec.decode(input);
} catch (IOException e) {
if (e.getMessage().startsWith("Invalid replay string table index")) {
// regenerate the replay file on this build; do not retry the same bytes
}
throw e;
} Prevention
- Record and replay with the identical compiler build.
- Checksum replay artifacts at capture time and verify before replay.
When it happens
Trigger: Reading a replay file (-Dgraal.ReplayCompilation / replay tooling) where a record refers to a string index not yet defined (or beyond EOF), or the file was produced by a compiler whose BinaryReplayCodec wrote a different table layout.
Common situations: Replaying compilation profiles across compiler builds (table order changed); truncated file transfers; bit rot in stored .glog/replay artifacts; hand-editing replay files.
Related errors
- Invalid replay string definition index
- Invalid replay symbolic method index
- Invalid replay symbolic method definition index
- Invalid replay registration index
- Registration is not a singleton
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/7e572fd9e91df4d7.
Report an issue: GitHub.