// voxen field notes

How to Update a Minecraft Plugin to 1.21 and 26.x (Even From Just the .jar)

· updated · 8 min read · [ GUIDE ] · by Matteo Orazietti

It's the most predictable failure in server administration: you update your server to Minecraft 1.21.11 or the new 26.x line, restart, and a plugin you've relied on for two years refuses to load. The developer abandoned it in 2022, the SpigotMC thread is dead, and your players want their crates back. This guide covers why plugins break between versions, how to update one by hand, and what to do when all you have left is the .jar.

Scope: this guide is about moving a plugin forward to a newer Minecraft version. If the Minecraft version is staying put and you are switching server platform — Spigot to Paper or Purpur — the breakages are different: read how to port a Spigot plugin to Paper and Purpur.

Why plugins break between Minecraft versions

A plugin is compiled against a specific version of the Bukkit/Spigot/Paper API. When Mojang changes the game, the API changes with it — and code written for the old API stops compiling, stops loading, or (worst case) loads and then throws errors mid-game. The usual suspects:

  • The api-version gate. Every plugin declares the API generation it targets in its plugin.yml. A server refuses to load plugins targeting a newer API than it has — that's the classic Unsupported API version console error.
  • Renamed and removed methods. API surface gets deprecated and eventually deleted. A plugin calling a method that no longer exists dies with NoSuchMethodError at runtime — often only when the specific feature is used.
  • The 1.13 Flattening. Minecraft 1.13 renamed essentially every material and block ID in the game. Any plugin from the 1.8–1.12 era that touches items or blocks needs its material handling rewritten.
  • Text components. Modern Paper moved from legacy ChatColor codes to the Adventure component API; old chat code increasingly triggers deprecation warnings and broken formatting.
  • NMS internals. Plugins that reach past the API into net.minecraft internals are version-locked by design — Mojang's internal names change every release. These are the hardest ports, sometimes impossible without a rewrite.
  • Java 25 on 26.x. 26.1 and newer need Java 25; 1.20.5 to 1.21.11 need Java 21. A plugin built with Java 25 carries class file version 69 and will not load on a Java 21 server, so the build must not target a Java newer than the one the server runs.
  • Unobfuscated jars on 26.1. From 26.1 Mojang ships server jars with real class, method and field names, and Paper removed its internal plugin remapper because Spigot moved to unobfuscated jars too. Plugins that use server internals with Spigot-mapped names, such as EntityHuman, do not work on 26.1+ on Paper or Spigot. Plugins that use only the Bukkit/Spigot/Paper API are not affected.
  • Version parsing. Code that reads the server version and assumes it starts with "1." breaks on 26.x: "26.2".split('.')[1] gives "2", which is not the minor version of a 1.x release.

Three errors account for most broken-plugin console logs:

terminal — paper 1.21 — the three classics
[ERROR]: Could not load 'plugins/crates.jar'
  org.bukkit.plugin.InvalidPluginException: Unsupported API version 1.16

[ERROR]: Error occurred while enabling Crates v2.3
  java.lang.NoSuchMethodError: org.bukkit.entity.Player.sendTitle(...)

[ERROR]: Could not load 'plugins/oldkits.jar'
  java.lang.ClassNotFoundException: net.minecraft.server.v1_16_R3.NBTTagCompound

Path 1: update it manually (you have the source)

If you have the plugin's source code and some Java, the manual route is well-trodden:

  1. Bump the build target. In pom.xml (or build.gradle), point the API dependency at the new version — e.g. io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT — and set Java 21 for 1.20.5 to 1.21.x, or Java 25 for 26.1 and newer. The Java version guide has the full table.
  2. Compile and read the errors. Every removed or renamed method surfaces as a compile error. Fix them one by one against the current API docs.
  3. Update api-version in plugin.yml to match your target.
  4. Hunt the silent breaks. Deprecated-but-still-present API compiles fine and misbehaves at runtime. Material names, chat formatting and scheduler usage deserve a test pass on a scratch server.

For a small plugin this is an afternoon. For anything with GUIs, persistence or version-specific hacks, budget considerably more — and it assumes you can read Java in the first place.

Path 2: you only have the .jar

This is the common case with abandoned plugins: the source was never published. A .jar can be decompiled — turned back into readable Java — with tools like CFR or Vineflower. Two honest caveats before you go down this road:

  • Rights first. Decompile plugins you own, commissioned, or whose license allows modification (open-source plugins generally do; premium plugins generally don't). Updating an abandoned free plugin for your own server is the typical legitimate case.
  • Obfuscated jars don't cooperate. Many premium plugins are deliberately scrambled before release. Decompiling those produces unreadable soup — no tool meaningfully recovers them.

Decompiled code compiles back fine, but you inherit the same manual migration work as Path 1 — on code with machine-generated variable names and no comments.

Path 3: let an AI port it (the Voxen way)

Voxen automates the whole chain — decompilation, API migration, recompilation — as a single flow called the Plugin Porter. It's the part of Voxen we built after watching how many "how do I update this plugin" threads end unresolved:

  1. Import. Upload the .jar (Voxen decompiles it server-side) or a source .zip, confirm you have the rights, and pick the target platform and version — say Paper 1.21.11 or 26.2 (Voxen builds up to 26.3).
  2. Port. The AI rewrites the code for the target API — events, materials, text components, api-version, build dependencies — and hands you a report of every change it made.
  3. Rebuild. The result is a normal Voxen project: hit BUILD, get a fresh .jar compiled against the real API of your target version, and install it like any other plugin. If the code needs more work, you keep iterating with the AI in the editor.
terminal — voxen porter — crates 1.16 → 26.2
[cfr ] decompiled 14 classes ................. ok
[ai  ] materials remapped (1.13 flattening) .. ok
[ai  ] ChatColor → Adventure components ...... ok
[ai  ] plugin.yml api-version → 26.2 ......... ok
[mvn ] BUILD SUCCESS (12.4s)
[out ] crates-2.4.0.jar · Paper 26.2

The same expectations apply as with any porting method, automated or not:

  • Obfuscated jars are detected and declined upfront, before spending anything.
  • NMS-heavy plugins get a warning and a partial port — internals code usually needs follow-up in the editor.
  • A port consumes one AI generation (the free plan includes five, so you can try it without paying).

Going from 1.21.11 to 26.x

1.21.11 was the last release with a 1. prefix. A move to 26.x touches more than the version string, so the jump gets its own checklist. Two guides go deeper: what 26.x changes for plugin developers, and how to check whether a plugin runs on 26.x.

  1. Back up the world and the plugins folder before changing anything.
  2. Install Java 25. 26.1 and newer need it; Java 21 is not enough.
  3. Update the dependencies before your plugin. Vault, ProtocolLib, PlaceholderAPI and any other plugin you rely on must support 26.x; an outdated one is a common cause of load failures after the jump.
  4. Set api-version in the 26.x form. Write major.minor, such as '26.1', not '26', and never a version newer than the server you run.
  5. Rebuild against paper-api 26.x. Copy the exact version string from the Paper docs rather than from memory, and compile with Java 25.
  6. Review NMS and reflection code. Any net.minecraft import or Spigot-mapped name such as EntityHuman needs a new build against the 26.x server classes. Plugins that use only the Bukkit/Spigot/Paper API are not affected.
  7. Test on a scratch server before production, and read the first console errors with the checklist above in hand.

Which path is yours?

Your situationBest path
Source available, you know JavaManual update — full control, an afternoon of work
Source available, no JavaAI port from the source .zip
Only the .jar, plugin abandonedAI port — decompile + migrate + rebuild in one flow
Obfuscated premium pluginContact the author — nothing else genuinely works
Heavy NMS/internals usageAI port for the scaffolding, expect manual finishing
Whatever the path: test the updated plugin on a scratch server before production, and back up your world first — a plugin that loads cleanly can still have version bugs in the features you use least. If you're deciding between updating a plugin and replacing it with something new, see how to make a plugin without coding.