Guidefor developers4 min read
Detecting the Minecraft version from plugin code after calendar versioning
getBukkitVersion() now returns 26.1.2.build.63-stable instead of 1.21.4-R0.1-SNAPSHOT, and code that parsed the old shape or assumed SemVer breaks. What Paper's own people say to use instead, and what to do if you still support Spigot.
The string that changed
A server running Paper 26.1.2 build 63 reports this:
This server is running Paper version 26.1.2-63-main@711c5de (2026-05-11T08:20:02Z)
(Implementing API version 26.1.2.build.63-stable)
That trailing value is what Bukkit.getBukkitVersion() returns. Where it used to be 1.21.4-R0.1-SNAPSHOT, it is now 26.1.2.build.63-stable. The suffix is not decoration either: a development build of the next drop reports 26.2.build.56-alpha.
The reason it looks like that is that it is the artifact version. io.papermc.paper:paper-api:26.1.2.build.63-stable is the dependency you compile against, and the method now hands you exactly that coordinate rather than a separately maintained API number.
It is not coming back
The issue asking for the old format was closed as working as intended. A Paper maintainer's reply was blunt about the premise: there has not been a distinct Bukkit API version for a decade, the API and the server are versioned together, Paper no longer ships SNAPSHOT releases, and SemVer compliance was never guaranteed. Bukkit, Spigot and Paper version numbers have sometimes looked like SemVer without ever meeting its rules about what a major or minor bump means.
The longer follow-up added the reasoning for the build number: an API method sometimes appears partway through a Minecraft version's build series, so a plugin that can see the build number can tell the operator to update to a later build of the same version rather than failing with something vague.
Worth noting for anyone still writing cross-platform code: Paper hard forked from Spigot at 1.21.4, and the maintainer's position is that a plugin supporting both should have code for each, because same-named methods can now return different values. Spigot was still reporting 26.1.1-R0.1-SNAPSHOT from the same method on a calendar version.
What to call instead
The concrete recommendation in that thread, from a Paper contributor and left uncontradicted by the maintainers who replied after it, was to use one of these:
// Paper, since ServerBuildInfo exists
String id = ServerBuildInfo.buildInfo().minecraftVersionId(); // "26.1.2", "25w46a"
// Paper, plain string on the Bukkit facade
String id = Bukkit.getMinecraftVersion(); // "26.1.2"
Both give you the version id Mojang uses, which is the point: it is a value someone else already defines, not a string Paper composed out of its own release process. ServerBuildInfo also exposes buildNumber() as an OptionalInt, buildTime(), gitCommit() and brandId(), so a plugin that genuinely needs "which build of 26.1.2" can ask for it as a number instead of parsing one out.
Neither is upstream Bukkit API. getMinecraftVersion() is marked in Paper's source as a Paper addition to the Server interface, and ServerBuildInfo is in the io.papermc.paper package. Plugin authors in two separate library issues reported both as unavailable on Spigot.
If you also support Spigot
Call the Paper method reflectively, verify the shape of what comes back, and only then fall back to a regex over the banner. That is precisely the fix a downstream library adopted after breaking:
String version = tryPaper() // Bukkit.getMinecraftVersion()
.filter(v -> v.matches("\\d+\\.\\d+(\\.\\d+)?"))
.orElseGet(() -> extractSemanticVersion(Bukkit.getServer().getVersion()));
The caveat is that the fallback is a heuristic and it will eventually be wrong again, which is the whole reason to try the real accessor first.
Do not parse the banner
Bukkit.getVersion() is a human readable line, and its tail differs per server software:
Spigot 1.21.11: 4573-Spigot-66411b9-d7d8774 (MC: 1.21.11)
Spigot 26.1.1: 4615-Spigot-4a90bec-63fe8dd (MC: 26.1)
Paper 1.21.11: 1.21.11-38-4446f17 (MC: 1.21.11)
Paper 26.1.1: 26.1.1-18-3d1da60 (MC: 26.1.1)
Note that Spigot's banner reports MC: 26.1 for a 26.1.1 server while Paper's reports MC: 26.1.1. Two shipped libraries broke on this class of parsing in 2026. Item NBT API misdetected the version on Paper's calendar builds and warned users that their perfectly supported server was unsupported, fixed in 2.15.7. TabooLib took the text after MC: and stripped one character, which on a Spigot build whose banner read MC: 1.21.11 Unobfuscated) produced the version name 1.21.11 Unobfuscated, matched nothing in its exact-match supported list, and told every user to wait for an update. Neither library was doing anything unreasonable by the standards of the format they were written against. The format simply is not one.
What still does not exist
There is no compatibility helper. An open request from 30 June 2026 asks Paper to expose the server's latest supported plugin API version with an isCompatible() method, on the grounds that everyone is currently writing custom matchers or gating on protocol versions instead. It has had no maintainer response, no assignee and no linked branch.
So the honest position today: get the Minecraft version id from ServerBuildInfo or Bukkit.getMinecraftVersion(), keep the comparison logic yours, and do not compare those ids as numbers. Sorting them correctly across the 1.x and calendar eras is its own problem, covered in how to sort Minecraft versions in code. If what you actually need is a stable integer to gate behaviour on rather than a name, protocol versions and data versions explains which of those is safe for what.

