elastic/elasticsearch · error · IOException
Invalid launch descriptor: bad magic number
Error message
Invalid launch descriptor: bad magic number
What it means
Thrown by LaunchDescriptor.checkMagic when the first int read from the stream does not equal the expected MAGIC constant. The magic number is a version/format guard at the head of the descriptor; a mismatch means the file/stream is not a launch descriptor at all, is a different/incompatible format, or is corrupted. IOException (checked).
Source
Thrown at libs/server-launcher-common/src/main/java/org/elasticsearch/server/launcher/common/LaunchDescriptor.java:196
String workingDir = in.readUTF();
String tempDir = in.readUTF();
boolean daemonize = in.readBoolean();
int serverArgsBytesLen = in.readInt();
byte[] serverArgsBytes = in.readNBytes(serverArgsBytesLen);
if (serverArgsBytes.length != serverArgsBytesLen) {
throw new IOException("Truncated server args: expected " + serverArgsBytesLen + " bytes, got " + serverArgsBytes.length);
}
return new LaunchDescriptor(command, jvmOptions, jvmArgs, environment, workingDir, tempDir, daemonize, serverArgsBytes);
}
/**
* Checks the magic number from the stream and throws if it doesn't match.
*/
protected static void checkMagic(DataInputStream in, int expectedMagic) throws IOException {
int magic = in.readInt();
if (magic != expectedMagic) {
throw new IOException("Invalid launch descriptor: bad magic number");
}
}
/**
* Returns a human-readable representation of this descriptor in a section-based text format.
* Useful for debugging with the launcher's --dump flag.
*/
public String toHumanReadable() {
StringBuilder sb = new StringBuilder();
appendSection(sb, "command", command);
appendSection(sb, "working_dir", workingDir);
appendSection(sb, "temp_dir", tempDir);
appendSection(sb, "daemonize", String.valueOf(daemonize));
appendSection(sb, "server_args_bytes", "<" + serverArgsBytes.length + " bytes>");
sb.append("[jvm_options]\n");
for (String opt : jvmOptions) {View on GitHub (pinned to db6a809a66)
Solutions
- Confirm the file was produced by a compatible launcher version (same MAGIC constant) — check the LaunchDescriptor.MAGIC value in both writer and reader.
- Verify the path passed to LaunchDescriptor.readFrom is the actual descriptor file, not another artifact.
- If the magic was intentionally changed, regenerate old descriptors with the new writer or add a migration path.
- Use the launcher's --dump flag to inspect the file's human-readable form if the magic check is bypassed for debugging.
Defensive patterns
Strategy: validation
Validate before calling
// Inspect the first 4 bytes before attempting a full parse.
try (RandomAccessFile raf = new RandomAccessFile(path.toFile(), "r")) {
int magic = raf.readInt();
if (magic != LaunchDescriptor.MAGIC) {
throw new IOException(path + " is not a valid launch descriptor (bad magic)");
}
} Try / catch
try {
return LaunchDescriptor.readFrom(path);
} catch (IOException e) {
throw new IOException(path + " is not a launch descriptor or is an incompatible version", e);
} Prevention
- Confirm writer and reader share the same MAGIC constant.
- Pass the actual descriptor path, not another artifact.
- Use --dump to inspect a descriptor when debugging magic mismatches.
When it happens
Trigger: Passing a path/stream to readFrom that is not a launch descriptor (e.g. a properties file, a script, an old format); byte-order mismatch (the magic was written big-endian and read little-endian); a truncated file where readInt returns a different 4 bytes; reading a descriptor written by a launcher with a different MAGIC value.
Common situations: Pointing the launcher at the wrong file (typo in path, stale symlink); mixing launcher versions where the MAGIC constant was changed; corruption of the first 4 bytes of the file.
Related errors
- Truncated server args: expected {} bytes, got {}
- Unable to resolve to resolve bwc versions from versionsFile.
- Cannot load VersionPropertiesBuildService
- Cannot resolve minimum compiler version via VersionPropertie
- unable to read the git revision
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/dda4026762ddb882.
Report an issue: GitHub.