Managing enrolments in Moodle is usually simple when everything is cleanly configured. But sometimes, after deleting old courses or changing the enrolment structure, Moodle may suddenly start showing this error when opening a course enrolment page:
Can't find data record in database.
This commonly happens when you go to:
Course → Participants → Enrolment methods
If this error appears only for some courses, there is a strong possibility that those courses still contain broken enrolment references from old Course meta link enrolment methods.
This tutorial explains why this happens, how to identify the broken records safely, and how to fix the issue properly using Moodle’s own API instead of directly deleting database rows.
Understanding the Problem
In Moodle, there are different enrolment methods. Two commonly confused methods are:
Course meta link
Cohort sync
They sound similar because both can automatically enrol users, but they work differently.
Course Meta Link
A Course meta link enrolment method allows users enrolled in one course to be automatically enrolled into another course.
Example:
Course A users → Course meta link → Course B
In this setup, Course A is the source course. Course B depends on Course A for enrolments.
This method is useful when you want one course to act as a master enrolment source for one or more other courses.
Cohort Sync
A Cohort sync enrolment method allows users from a Moodle cohort to be automatically enrolled into a course.
Example:
Cohort → Cohort sync → Course B
This is usually better when you want to manage users centrally from one group and attach that group directly to multiple courses.
For large Moodle setups with many courses, Cohort sync is usually cleaner than creating one course just to act as an enrolment source for other courses.
Why the Error Happens
Suppose earlier you had this structure:
Master Course → Course meta link → Course 1
Master Course → Course meta link → Course 2
Master Course → Course meta link → Course 3
Later, you deleted the old Master Course because you decided to use cohorts directly.
Now Moodle may still have some old meta enrolment records inside the affected courses. These records may still point to the deleted source course.
So when Moodle opens:
Participants → Enrolment methods
it tries to load the old linked source course.
But that source course no longer exists.
So Moodle throws:
Can't find data record in database.
This is not usually a permission issue. It is normally a broken reference issue.
Most Likely Cause
The most likely cause is an orphaned Course meta link record in the Moodle enrol table.
In Moodle, enrolment methods are stored in the enrolment table. For Course meta link enrolment, Moodle stores the linked source course ID in the customint1 field.
So if the old source course was deleted, you may have a record like this:
enrol = meta
customint1 = deleted source course ID
That means Moodle still thinks the course is linked to another course, but the linked course no longer exists.
Before You Start
Do not directly delete database records without a backup.
This fix touches enrolment records, so you should first:
- Take a full database backup.
- Identify the broken records.
- Remove them using Moodle’s enrolment API.
- Clear cache.
- Run cron.
- Recheck the affected courses.
Step 1: Identify Broken Course Meta Links
Log in to your Moodle database and run the following SQL query.
Replace mdl_ with your actual Moodle table prefix if your Moodle installation uses a different prefix.
SELECT
e.id AS enrol_instance_id,
e.courseid AS target_course_id,
target.shortname AS target_shortname,
target.fullname AS target_course_name,
e.customint1 AS missing_source_course_id
FROM mdl_enrol e
JOIN mdl_course target ON target.id = e.courseid
LEFT JOIN mdl_course source ON source.id = e.customint1
WHERE e.enrol = 'meta'
AND source.id IS NULL;
This query checks all Course meta link enrolment methods and finds records where the source course no longer exists.
If the query returns rows, those are broken meta enrolment records.
Example output:
enrol_instance_id | target_course_id | target_shortname | target_course_name | missing_source_course_id
101 | 25 | linux-basic | Linux Basic Course | 7
102 | 26 | devops-basic | DevOps Basic Course | 7
Meaning:
target_course_id = course where the enrolment method page may be breaking
missing_source_course_id = deleted old course that was previously linked
In this example, course ID 7 was deleted, but courses 25 and 26 still have meta enrolment records pointing to it.
Step 2: Take a Database Backup
Before making any change, take a Moodle database backup.
For MySQL or MariaDB:
mysqldump -u DBUSER -p DBNAME > moodle_before_fix_broken_meta_links.sql
Example:
mysqldump -u moodleuser -p moodledb > moodle_before_fix_broken_meta_links.sql
For large production Moodle sites, also confirm that you have a proper server backup or snapshot.
Do not skip this step. Enrolment records affect user access to courses.
Step 3: Create a Moodle CLI Script to Remove Broken Meta Links
The safest way is to remove the broken enrolment instances using Moodle’s API.
Do not simply run a DELETE FROM mdl_enrol query unless you fully understand all related records. Moodle enrolment methods may have associated user enrolments, roles, events, and plugin-level cleanup logic.
Go to your Moodle root directory and create a new CLI script:
nano admin/cli/fix_broken_meta_links.php
Paste the following code:
<?php
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->libdir . '/enrollib.php');
global $DB;
$plugin = enrol_get_plugin('meta');
if (!$plugin) {
cli_error('Course meta link enrolment plugin not found.');
}
$sql = "
SELECT e.*
FROM {enrol} e
LEFT JOIN {course} source ON source.id = e.customint1
WHERE e.enrol = :enrol
AND source.id IS NULL
";
$instances = $DB->get_records_sql($sql, ['enrol' => 'meta']);
if (!$instances) {
mtrace('No broken course meta link enrolment instances found.');
exit(0);
}
mtrace('Found ' . count($instances) . ' broken course meta link instance(s).');
foreach ($instances as $instance) {
mtrace(
'Deleting broken meta enrol instance ID ' . $instance->id .
' from target course ID ' . $instance->courseid .
', missing source course ID ' . $instance->customint1
);
$plugin->delete_instance($instance);
}
mtrace('Done.');
Save and exit.
This script does the following:
Finds all Course meta link enrolment instances
Checks whether the linked source course exists
Finds records where the source course is missing
Deletes the broken enrolment instance using Moodle's enrolment API
Step 4: Run the Script
From your Moodle root directory, run:
php admin/cli/fix_broken_meta_links.php
Example output:
Found 3 broken course meta link instance(s).
Deleting broken meta enrol instance ID 101 from target course ID 25, missing source course ID 7
Deleting broken meta enrol instance ID 102 from target course ID 26, missing source course ID 7
Deleting broken meta enrol instance ID 103 from target course ID 27, missing source course ID 7
Done.
If there are no broken records, you may see:
No broken course meta link enrolment instances found.
In that case, the issue may be related to another broken enrolment method, missing context record, deleted role, or third-party enrolment plugin.
Step 5: Purge Moodle Cache
After deleting broken enrolment instances, purge Moodle cache.
Run:
php admin/cli/purge_caches.php
This ensures Moodle does not continue using old cached enrolment or course data.
Step 6: Run Moodle Cron
Now run Moodle cron:
php admin/cli/cron.php
You can run it more than once:
php admin/cli/cron.php
php admin/cli/cron.php
Cron helps Moodle process pending cleanup tasks, enrolment syncs, deleted contexts, and scheduled maintenance operations.
Step 7: Run Context Cleanup If Needed
If the error still appears and the debug message mentions context, run Moodle’s context cleanup task.
php admin/tool/task/cli/schedule_task.php --execute='\core\task\context_cleanup_task' --showdebugging
This helps clean up broken or orphaned context records caused by deleted courses, categories, users, or enrolment structures.
Step 8: Recheck the Course
Now open the affected course again:
Course → Participants → Enrolment methods
The page should now load normally.
If the old Course meta link was the cause, the broken enrolment method should be gone.
Now you can add the correct enrolment method:
Add method → Cohort sync
Select your cohort and assign the correct role, usually:
Student
Step 9: Move from Course Meta Link to Cohort Sync
If your goal is to give one group of users access to many courses, Cohort sync is usually the cleaner approach.
Old approach:
Users enrolled in Master Course
↓
Course meta link
↓
Users get access to other courses
Better approach:
Users added to Cohort
↓
Cohort sync
↓
Users get access to required courses
This is easier to manage because cohorts are designed for grouping users at the site or category level.
Step 10: Bulk Add Cohort Sync to Many Courses
If you have hundreds of courses, adding Cohort sync manually one by one is painful.
Instead, use Moodle’s Upload courses feature.
Go to:
Site administration → Courses → Upload courses
Prepare a CSV file like this:
shortname,enrolment_1,enrolment_1_cohortidnumber,enrolment_1_role
COURSE001,cohort,premium_students,student
COURSE002,cohort,premium_students,student
COURSE003,cohort,premium_students,student
Where:
shortname = existing Moodle course shortname
enrolment_1 = cohort
enrolment_1_cohortidnumber = Cohort ID
enrolment_1_role = role to assign, usually student
Important: enrolment_1_cohortidnumber should match the Cohort ID, not just the cohort display name.
Then upload the CSV with:
Upload mode: Update existing courses only
Update mode: Update with CSV data
Always preview before applying changes.
Useful SQL Queries for Troubleshooting
Check enrolment methods for one course
Replace 123 with your course ID.
SELECT
e.id,
e.enrol,
e.status,
e.courseid,
e.roleid,
e.customint1,
e.customint2,
e.customchar1
FROM mdl_enrol e
WHERE e.courseid = 123
ORDER BY e.sortorder, e.id;
Find broken meta enrolments
SELECT
e.id,
e.courseid,
target.shortname AS target_course,
e.customint1 AS missing_source_course_id
FROM mdl_enrol e
JOIN mdl_course target ON target.id = e.courseid
LEFT JOIN mdl_course source ON source.id = e.customint1
WHERE e.enrol = 'meta'
AND source.id IS NULL;
Find enrolment records pointing to missing courses
SELECT e.*
FROM mdl_enrol e
LEFT JOIN mdl_course c ON c.id = e.courseid
WHERE c.id IS NULL;
Find user enrolments pointing to missing enrolment instances
SELECT ue.*
FROM mdl_user_enrolments ue
LEFT JOIN mdl_enrol e ON e.id = ue.enrolid
WHERE e.id IS NULL;
Find cohort sync records pointing to missing cohorts
SELECT e.*
FROM mdl_enrol e
LEFT JOIN mdl_cohort ch ON ch.id = e.customint1
WHERE e.enrol = 'cohort'
AND e.customint1 IS NOT NULL
AND ch.id IS NULL;
Best Practices to Avoid This Issue in Future
1. Do not use courses as enrolment containers unless necessary
If your goal is to manage groups of users, use cohorts.
Better:
Cohort → Courses
Avoid unnecessary dependency like:
Master Course → Other Courses
2. Before deleting courses, check meta links
Before deleting any old master/source course, check whether other courses are using it as a Course meta link source.
You can run:
SELECT
e.id,
e.courseid AS target_course_id,
target.shortname AS target_course,
e.customint1 AS source_course_id,
source.shortname AS source_course
FROM mdl_enrol e
JOIN mdl_course target ON target.id = e.courseid
JOIN mdl_course source ON source.id = e.customint1
WHERE e.enrol = 'meta';
This shows which courses depend on which source courses.
3. Use Cohort sync for large-scale access
For large Moodle installations with many courses, Cohort sync is easier to maintain.
Example:
SEO Students Cohort → 50 SEO Courses
DevOps Students Cohort → 80 DevOps Courses
SRE Students Cohort → 40 SRE Courses
4. Keep regular database backups
Before deleting courses, categories, cohorts, or enrolment methods, always keep a backup.
5. Run cron regularly
Moodle cron should run every minute or as recommended for your Moodle version and server environment.
Example crontab:
* * * * * /usr/bin/php /path/to/moodle/admin/cli/cron.php >/dev/null
Final Summary
If Moodle shows this error:
Can't find data record in database.
when opening:
Course → Participants → Enrolment methods
and you recently deleted old linked courses, the most likely cause is a broken Course meta link enrolment record.
The deleted course was probably still referenced by another course through a meta enrolment method.
The safest fix is:
1. Find broken meta enrolment records
2. Backup the database
3. Remove broken records using Moodle API
4. Purge caches
5. Run cron
6. Recheck enrolment methods page
7. Move to Cohort sync for future course access
The important lesson is this:
Course meta link depends on another course.
Cohort sync depends on a cohort.
If you delete the source course used by Course meta link, Moodle may break when trying to load the enrolment method. But if you use Cohort sync properly, user access is cleaner, easier to manage, and much better for hundreds of courses.
References
- Moodle Docs: Course meta link enrolment
https://docs.moodle.org/en/Course_meta_link_enrolment - Moodle Developer Resources: Enrolment plugins
https://moodledev.io/docs/4.5/apis/plugintypes/enrol - Moodle GitHub: Course meta link enrolment code
https://github.com/moodle/moodle/blob/MOODLE_405_STABLE/enrol/meta/lib.php - Moodle Docs: Course enrolment
https://docs.moodle.org/en/Course_enrolment