{"record":{"id":"dda4026762ddb882","repo":"elastic/elasticsearch","slug":"invalid-launch-descriptor-bad-magic-number","errorCode":null,"errorMessage":"Invalid launch descriptor: bad magic number","messagePattern":"Invalid launch descriptor: bad magic number","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libs/server-launcher-common/src/main/java/org/elasticsearch/server/launcher/common/LaunchDescriptor.java","lineNumber":196,"sourceCode":"        String workingDir = in.readUTF();\n        String tempDir = in.readUTF();\n        boolean daemonize = in.readBoolean();\n        int serverArgsBytesLen = in.readInt();\n        byte[] serverArgsBytes = in.readNBytes(serverArgsBytesLen);\n        if (serverArgsBytes.length != serverArgsBytesLen) {\n            throw new IOException(\"Truncated server args: expected \" + serverArgsBytesLen + \" bytes, got \" + serverArgsBytes.length);\n        }\n\n        return new LaunchDescriptor(command, jvmOptions, jvmArgs, environment, workingDir, tempDir, daemonize, serverArgsBytes);\n    }\n\n    /**\n     * Checks the magic number from the stream and throws if it doesn't match.\n     */\n    protected static void checkMagic(DataInputStream in, int expectedMagic) throws IOException {\n        int magic = in.readInt();\n        if (magic != expectedMagic) {\n            throw new IOException(\"Invalid launch descriptor: bad magic number\");\n        }\n    }\n\n    /**\n     * Returns a human-readable representation of this descriptor in a section-based text format.\n     * Useful for debugging with the launcher's --dump flag.\n     */\n    public String toHumanReadable() {\n        StringBuilder sb = new StringBuilder();\n\n        appendSection(sb, \"command\", command);\n        appendSection(sb, \"working_dir\", workingDir);\n        appendSection(sb, \"temp_dir\", tempDir);\n        appendSection(sb, \"daemonize\", String.valueOf(daemonize));\n        appendSection(sb, \"server_args_bytes\", \"<\" + serverArgsBytes.length + \" bytes>\");\n\n        sb.append(\"[jvm_options]\\n\");\n        for (String opt : jvmOptions) {","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/server-launcher-common/src/main/java/org/elasticsearch/server/launcher/common/LaunchDescriptor.java#L178-L214","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Inspect the first 4 bytes before attempting a full parse.\ntry (RandomAccessFile raf = new RandomAccessFile(path.toFile(), \"r\")) {\n    int magic = raf.readInt();\n    if (magic != LaunchDescriptor.MAGIC) {\n        throw new IOException(path + \" is not a valid launch descriptor (bad magic)\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return LaunchDescriptor.readFrom(path);\n} catch (IOException e) {\n    throw new IOException(path + \" is not a launch descriptor or is an incompatible version\", e);\n}","preventionTips":["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."],"tags":["launcher","io","serialization","descriptor","versioning"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}