Transform Learning with a Powerful Enterprise LMS

Learn more
Moodle

Moodle version.php Explained: requires, supported, incompatible and maturity

Every Moodle plugin needs a version.php. This reference explains each property, how core uses it during install and upgrade, the errors a wrong value causes, and the core version numbers for 5.0 to 5.3.

Learn more about this topic with AI

Gemini opens with the prompt copied - paste it into the chat to start.

Illustration of a Moodle plugin version.php file with requires, supported and maturity properties

Moodle version.php is the small metadata file every plugin must have in its root directory. It tells Moodle the plugin's frankenstyle name ($plugin->component), its version number, the oldest Moodle it runs on (requires), the Moodle branches it supports or cannot run on (supported and incompatible), how stable the release is (maturity), a human-readable release name and any other plugins it depends on. Moodle reads it to decide whether a plugin needs installing or upgrading, and whether it is allowed to.

Two properties are mandatory in practice: component and version. Without either, the upgrade stops with a "defective" plugin error. The rest are optional but shape what administrators see on the Plugins check page and whether an install goes ahead.

Checked against the Moodle 5.3.0 source (public/lib/upgradelib.php, public/lib/classes/plugin_manager.php, public/lib/classes/plugininfo/base.php) and the version.php page in the Moodle developer documentation (October 2026).

A complete example

A local plugin that needs Moodle 5.0 or later and has been tested on 5.0 to 5.3:

<?php
// GPL header omitted for brevity.

/**
 * Version information for local_example.
 *
 * @package   local_example
 * @copyright 2026 Your Name
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

defined('MOODLE_INTERNAL') || die();

$plugin->component = 'local_example';
$plugin->version   = 2026110300;        // YYYYMMDDXX.
$plugin->requires  = 2025041400.00;     // Moodle 5.0.
$plugin->supported = [500, 503];        // Moodle 5.0 to 5.3.
$plugin->maturity  = MATURITY_STABLE;
$plugin->release   = '1.2.0';
$plugin->dependencies = [
    'mod_forum' => ANY_VERSION,
];

Not run on a live site; test on staging first. The file holds assignments to $plugin and nothing else.

Property reference

PropertyTypeNeeded?What core does with it
componentstringYesMust equal type_name for the directory the plugin sits in; otherwise the upgrade stops
versionintegerYesCompared with the version stored in config_plugins to decide install, upgrade or downgrade
requiresnumberRecommendedInstall or upgrade is refused if it is higher than the site's core $version
supportedarray of two integersOptional (3.9+)Shown as a branch range on the Plugins check page; a malformed value throws a coding exception
incompatibleintegerOptional (3.9+)Install or upgrade is refused when the site's branch is equal or higher
maturityconstantRecommendedUsed by update notifications and the "Required code maturity" setting
releasestringRecommendedDisplay only
dependenciesarrayOptionalEach listed plugin must be present at the given version or later

version: the number that triggers upgrades

The format is YYYYMMDDXX: the release date plus a two-digit counter for that day. Moodle stores the installed value in config_plugins (plugin = your component, name = version) and compares it with the file on disk:

  • No stored value: the plugin is new and is installed from db/install.xml.
  • Disk higher than stored: the plugin is upgraded, running your db/upgrade.php steps.
  • Disk lower than stored: the Plugins check page shows "Higher version already installed!" and the upgrade throws "Cannot downgrade ... from ... to ...".

Every release must increase the number. If you maintain several stable branches, the developer docs recommend freezing the date part at the branch point and using the XX counter on that branch, so that every newer branch starts with a higher YYYYMMDD00 than any older one. Get this wrong and a site moving between your branches hits the downgrade error; our article on the Moodle "Cannot downgrade" plugin error covers the recovery.

Each upgrade step in db/upgrade.php ends with a savepoint call (for example upgrade_plugin_savepoint()) carrying the step's version. Core refuses a savepoint that is not higher than the stored version, so two steps with the same number throw "Cannot downgrade". A step numbered above the value in version.php is just as bad: it stores the higher number, and from then on the file on disk looks older than the database. Bump version.php to at least the number of your newest upgrade step.

requires: the minimum Moodle version

requires is compared with core's $version from the root version.php. If it is higher, the upgrade stops with: "Plugin ... could not be installed. It requires a newer version of Moodle (currently you are using ..., you need ...)". A value below 2010000000 is treated as a pre-2.0 plugin and rejected as defective.

Use the exact core version number of the oldest release you support. These are the x.y.0 values from the Moodle source tags:

ReleaseCore $version$branch
Moodle 5.02025041400.00500
Moodle 5.12025100600.00501
Moodle 5.22026042000.00502
Moodle 5.32026100500.00503

To find the number for any other release, open the root version.php of that release (in 5.1 and later it is public/version.php) and copy $version. Point releases increase it, so a plugin that needs a fix from 5.3.2 should require the 5.3.2 value, not the 5.3.0 one.

supported and incompatible: branch ranges

Both properties use branch numbers, not version numbers: 500 for 5.0, 503 for 5.3, 405 for 4.5. They were added in Moodle 3.9 (MDL-59562).

supported is an inclusive range, [lowest, highest]. In the 5.3 source, core validates its shape (exactly two integers, low not above high) and throws a coding exception otherwise. It then uses it for display: the Plugins check page shows "Moodle 500 - 503" in the requirements column. It does not block installation on a branch outside the range; the install and upgrade code checks only requires and incompatible.

incompatible is the first branch the plugin cannot run on. When the site's $CFG->branch is equal or higher, install and upgrade stop with "Plugin ... does not support this version of Moodle ...". Set it when you know a later branch breaks the plugin, for example after a Moodle release removes an API you depend on:

$plugin->supported    = [500, 503];
$plugin->incompatible = 504;   // Blocks Moodle 5.4 and later.

Be careful with incompatible: it blocks the whole site upgrade until the plugin is updated or removed. That is the right outcome for a plugin that would corrupt data on a newer branch, but it is a heavy tool for "not tested yet". Use supported to say what you tested. If an upgrade is already blocked, see Moodle plugin not compatible after upgrade.

maturity: what it controls

ConstantValueAdmin label
MATURITY_ALPHA50Alpha
MATURITY_BETA100Beta
MATURITY_RC150Release candidate
MATURITY_STABLE200Stable version

A plugin's maturity does not stop it installing. It feeds the update notification system: under Site administration > Server > Update notifications, the "Required code maturity" setting (default Stable version) hides available updates below that level. Per the setting's own description, updates for plugins that do not declare a maturity are always reported. When several updates are available, core prefers the most mature, and treats an undeclared maturity as between release candidate and stable. Declare it.

component and dependencies

component is the full frankenstyle name, such as local_example or mod_example. During upgrade, a missing value stops with "Missing $plugin->component declaration in version.php", and a value that does not match the directory stops with "Plugin ... is installed in incorrect location ..., expected location is ...". The usual cause is a zip extracted to the wrong folder or a renamed directory. Our guide to Moodle plugin types lists where each type must live.

dependencies maps other components to a minimum version, or to ANY_VERSION when any installed version will do. If a dependency is missing or too old, the Plugins check page marks the requirement as failed and the upgrade cannot continue.

Rules for the file itself

  • No includes. The developer docs state that version.php must never contain require_once or any other file inclusion. Core reads it with a plain include from several places, including the check that decides whether the site needs upgrading, so it has to stay a side-effect-free data file. Declaring a function or class there can also cause a "cannot redeclare" fatal error when the file is read twice in one request.
  • Start with the guard. defined('MOODLE_INTERNAL') || die(); stops direct web access.
  • Use $plugin, not $module. In 5.3, the plugin manager prints a debugging message when the old activity-module $module syntax is used.
  • Literal values only. No conditions, no reading config. The file must give the same answer every time it is read.

Common mistakes and the errors they cause

MistakeWhat you see
Version not increased after a schema changeNo upgrade runs; new tables or fields are missing
Version lower than an earlier release"Cannot downgrade ..."
requires set to a newer core than the site"It requires a newer version of Moodle ..."
supported with three values or stringsCoding exception: incorrect syntax in plugin supported declaration
incompatible set to the current branch"... does not support this version of Moodle ..."
component does not match the folder"... is installed in incorrect location ..."

For the wider development workflow, including upgrade code and testing, start with our Moodle guide.

How we can help

We build and maintain Moodle plugins across several stable branches, including version numbering, upgrade steps and CI against each supported release. See our Moodle plugin development service or tell us about your plugin.

Frequently asked questions

What is version.php in Moodle?

It is the mandatory metadata file in the root of every Moodle plugin. It sets the plugin's component name, version number, minimum Moodle version, supported branches, maturity, release name and dependencies, which Moodle uses during install and upgrade.

What is the difference between requires and supported in Moodle version.php?

requires is a single core version number (for example 2026100500.00 for Moodle 5.3) and installation is refused on older sites. supported is a pair of branch numbers such as [500, 503] showing the tested range; in Moodle 5.3 it is displayed on the Plugins check page but does not block installation.

How do I find the Moodle version number for requires?

Open the root version.php of the Moodle release you want as the minimum (public/version.php in 5.1 and later) and copy the $version value. Use the point release you actually need, because point releases have higher numbers.

Can I use require_once in Moodle version.php?

No. The Moodle developer docs say version.php must never contain require_once or any other file inclusion. Core reads the file in performance-sensitive paths, so it must contain only assignments to $plugin.

What does $plugin->maturity do?

It declares how stable the release is (alpha, beta, release candidate or stable). It does not stop installation; it controls which available updates are reported, based on the Required code maturity setting under Site administration > Server > Update notifications.

Free 30-minute consultation

Not sure where to start? Talk to an LMS engineer.

Tell us what platform you run and what you need. You’ll get honest, practical advice - even if the answer is that you don’t need us.

Sources & references

  1. version.php - Moodle developer documentation
  2. Common files - Moodle developer documentation
  3. Moodle 5.3.0 upgradelib.php - Moodle (GitHub)
  4. MDL-59562: plugin supported and incompatible versions - Moodle Tracker
Add as a preferred source on Google

Add All-in-One LMS as a preferred source to see more of our articles in Google’s Top Stories.

Learn more about this topic with AI

Gemini opens with the prompt copied - paste it into the chat to start.

Keep reading

Before you go - get a free LMS audit

Tell us which LMS you use and what is not working. An engineer replies within one business day.

Choose which optional cookies we may use. You can change this at any time from "Cookie preferences" in the footer. Cookie policy · Privacy policy