Menu

Guidefor developers5 min read

plugin.yml api-version values for Minecraft 26.x servers

Bukkit api-version accepted 1.13 through 1.21, then calendar values arrived. What to declare for 26.1 and 26.2, and why a wrong value blocks loading.

What api-version actually does

api-version is a contract statement, not a dependency declaration. It tells the server which generation of the Bukkit API your jar was compiled against, so the server can decide whether to load the plugin directly, load it through a compatibility layer, or refuse it outright. The server reads it while parsing the descriptor, before any of your code runs.

Three consequences follow from that:

  • The value names a version family, not a specific release.
  • It is checked against a fixed list compiled into the server jar you are running.
  • A wrong value is a load-time failure. Your plugin never gets an onEnable call, and anything that lists it as a dependency fails to enable as well.

Accepted values before the calendar change

The field arrived with Minecraft 1.13, the release that flattened block and item identifiers. Before that there was nothing to declare, because there had been no break large enough to need one. From 1.13 onward, each new minor family added one accepted value.

ValueFirst release in familyLast release in family
1.131.13, 18 July 20181.13.2
1.141.14, 23 April 20191.14.4
1.151.15, 9 December 20191.15.2
1.161.16, 23 June 20201.16.5
1.171.17, 8 June 20211.17.1
1.181.18, 30 November 20211.18.2
1.191.19, 7 June 20221.19.4
1.201.20, 2 June 20231.20.6
1.211.21, 13 June 20241.21.11, 9 December 2025

The 1.21 family is the useful one to look at. It ran for twelve releases across roughly eighteen months, and one api-version value covered all of them. That is the granularity the field works at.

Quote the value. This is the single most common way the field goes wrong:

api-version: 1.20     # YAML reads this as the number 1.2
api-version: "1.20"   # correct

Unquoted, 1.20 is a valid floating point literal, so the YAML parser hands the server 1.2, which is not an accepted value. The same trap is waiting in the calendar era for any family whose second component ends in a zero.

Declaring 26.1 and 26.2

Calendar versioning changed the version numbers, not the rule. 26.1 and 26.2 are families in exactly the same sense that 1.21 was.

ValueCoversJava required
26.126.1, 26.1.1, 26.1.225
26.226.225

So for a plugin targeting the current release:

name: ExamplePlugin
version: 1.0.0
main: com.example.ExamplePlugin
api-version: "26.2"

There is no value that means "1.22". That release never existed, and no server jar has it in its accepted list. If you see api-version: "1.22" in a plugin, it was written by someone guessing at the numbering, and it will fail on every server ever built.

What happens when the value is unknown to the server

The server compares your declared value against its own compiled list. If the value is absent from that list, the plugin is rejected during load with an unsupported API version message and never reaches onEnable.

That happens in three situations:

  1. You declared a newer version than the server runs. A jar declaring 26.2 will not load on a 1.21.11 server. The 1.21.11 jar was built in December 2025 and has no knowledge of a value that did not exist until March 2026.
  2. You declared something that is not a real family. 1.22, 26.2.1, 1.21.11 and 26 all fall here.
  3. YAML rewrote your value. The unquoted number case above.

The failure is loud and immediate, which is the point of the design. A plugin compiled against API surface the server does not have would otherwise die with a NoSuchMethodError somewhere deep in a listener, at whatever moment the missing method was first reached.

Legacy mode and why you do not want it

Omitting api-version entirely is not the same as declaring an old one. A descriptor with no api-version key is treated as pre-1.13 and the server applies a translation layer to it: material names, data values and enchantment identifiers get mapped from the old world into the current one on every call that crosses the boundary.

This exists so that plugins abandoned before 2018 keep working. It is not a target you should be building for. Legacy mode adds a per-call cost, it cannot translate anything added after 1.13, and it silently changes the meaning of some API calls rather than failing on them. It is also not guaranteed to survive. Whether a given calendar-era server still loads a descriptor with no api-version at all is a property of that specific server build, so test it rather than assuming it.

If your plugin is new, always declare a value.

Choosing the lowest value you can still support

api-version sets a floor, not a ceiling. Declaring 1.21 on a 26.2 server is fine as long as 1.21 is still in that server's accepted list, and it means your jar loads on 1.21 servers too. The cost is that you accept every behaviour change made to the API since that value, without the server warning you about any of them.

A workable rule:

  • Declare the oldest family you actually build and test against.
  • Raise the value when you start calling API that did not exist earlier, not on a schedule.
  • Never declare a family newer than the oldest server you want to support, because that is a hard rejection rather than a degradation.

Where a single value cannot cover your range, ship two jars rather than one jar with a value that lies. Check the Paper build history for which game versions currently have builds, and the 26.2 compatibility page for what the rest of the ecosystem has declared support for.

What could change

The accepted value list grows with every new Minecraft family, so 26.3 becomes a valid value when that release ships and not before. Server projects also periodically drop the oldest entries and the legacy translation layer, which turns a previously working old value into a rejection. Both changes are observable in one place: the accepted list compiled into the server jar you are targeting. Read it from the jar itself, or check the release notes for the build you downloaded from the Paper page. Version families and their release dates on this site come from Mojang's own version manifest, listed at all Minecraft versions.

Frequently asked

What api-version should I set for 26.2?

Set api-version: "26.2". Quote it. That value covers every patch release in the 26.2 family, the same way 1.21 covered all twelve releases from 1.21 to 1.21.11.

Can I still declare 1.13 on a 26.2 server?

An old value is accepted as long as it is still in the server's compiled list, and it does not put the plugin into legacy mode the way omitting the key does. It does mean you accept every API behaviour change made since 1.13, so only declare it if you have tested against a recent server.

Why does my plugin refuse to enable with an unsupported API version message?

The value you declared is not in the list compiled into that server jar. Almost always this is a plugin built for a newer Minecraft version than the server runs, or an unquoted value that YAML turned into a different number.

Does api-version include the patch number?

No. The value names a version family, not a release. Declare 26.2, not 26.2.1, and 1.21, not 1.21.11. If you genuinely need to distinguish two releases inside one family, read the accepted list compiled into the server jar rather than guessing at a patch-level value.

Referenced on this site

Last reviewed 2026-07-27. Version data on this site updates automatically; this guide is reviewed by hand when the ecosystem changes.