You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I need to announce an upcoming breaking change that I know will inconvenience some Cronicle users, especially those who have been running stable installations for many years.
Starting with Cronicle v0.9.127, Cronicle requires Node.js v22.12.0 or later. Please note the full version number. Node.js v22.0 through v22.11 will not be sufficient.
This requirement arrived indirectly with an urgent dependency update in v0.9.127, which is why users on older Node.js releases currently see a confusing ERR_REQUIRE_ESM message rather than a clear version warning. The next Cronicle patch release will add an explicit installer and startup check so the requirement is communicated properly.
I am genuinely sorry to impose this upgrade. I know that a runtime upgrade can turn an otherwise routine Cronicle update into real maintenance work. This is particularly difficult for people running CentOS 7, Amazon Linux 2, older NAS devices, and other systems whose C libraries are too old for the official Node.js v22 Linux binaries.
This was not a casual decision. The change is being forced by security updates in Cronicle's dependency chain. This post explains what changed, why we cannot safely avoid it, and how to upgrade on both current and legacy Linux systems.
Short Version
Cronicle v0.9.127 and later require Node.js v22.12.0 or later.
Please upgrade Node.js on every Cronicle server before upgrading to v0.9.127 or later.
Your Cronicle configuration and stored data do not need to be recreated.
Users on current operating systems can use a normal official Node.js v22 installation.
Users on x86_64 CentOS 7, Amazon Linux 2, and similar legacy systems may need the community-maintained linux-x64-glibc-217 Node.js build described below.
Existing installations of Cronicle v0.9.126 or earlier will not suddenly stop. The requirement takes effect when you install v0.9.127 or later.
Why This Is Necessary
Cronicle uses sanitize-html to protect custom HTML job reports against cross-site scripting and related attacks. Recent sanitize-html releases corrected multiple sanitizer bypasses. Some of these fixes required an upgrade to htmlparser2 v12 so that the sanitizer and a real browser agree about how certain unusual combinations of HTML, SVG, MathML, and raw-text elements are parsed.
That upgrade introduced an unavoidable runtime requirement:
sanitize-html is a CommonJS module.
htmlparser2 v12 and its related packages are ECMAScript modules.
sanitize-html must load htmlparser2 synchronously to preserve its existing synchronous API.
Node.js v22.12.0 is the first supported Node.js 22 release that allows CommonJS code to load a compatible ECMAScript module without an experimental command-line flag.
As a result, sanitize-html now explicitly requires Node.js >=22.12.0.
On Node.js v18, Cronicle fails during startup with an error similar to this:
Error [ERR_REQUIRE_ESM]: require() of ES Module .../htmlparser2/dist/index.js
from .../sanitize-html/index.js not supported.
This error is independent of Debian, CentOS, Amazon Linux, or macOS. The operating system only becomes relevant when attempting to install a sufficiently new Node.js binary.
Between a Rock and a Hard Place
As maintainers, we effectively have three choices:
Stop upgrading dependencies and knowingly allow security vulnerabilities to accumulate in Cronicle.
Rewrite and maintain all affected dependencies in house.
Continue applying upstream security updates, even when an upstream dependency raises its minimum supported Node.js version.
The first choice is not responsible for software that receives and displays user-controlled data. The second is not realistic for a small open source project. Cronicle simply does not have the manpower to replace and continuously security-audit mature projects such as sanitize-html, htmlparser2, and all of their supporting packages.
That leaves the third choice. We are upgrading the dependencies so Cronicle receives the security fixes, but doing so forces us to raise Cronicle's Node.js floor to v22.12.0.
I do not like requiring users to upgrade a working runtime, but shipping a scheduler with known, preventable security weaknesses would be worse. I am truly sorry for the extra work required to keep Cronicle running and up to date.
Who Needs to Take Action?
Run these commands on every Cronicle server, including workers and backup-primary servers:
node --version
npm --version
command -v node
Use the following table to determine what you need to do:
Installed Node.js version
Action
v16, v18, or older
Upgrade before upgrading Cronicle
v20
Upgrade before upgrading Cronicle
v22.0 through v22.11
Upgrade to at least v22.12.0
v22.12.0 or newer
You're good to go.
A newer supported LTS release
Meets the version requirement, provided your OS supports it
I recommend installing the newest available patch release in the Node.js v22 LTS line rather than installing exactly v22.12.0. Newer patch releases include additional bug and security fixes.
Before You Upgrade
Please take a few minutes to inventory and back up your installation first.
1. Check Every Server
For a multi-server Cronicle cluster, repeat the version checks on every machine. Do not assume that all workers have the same Node.js version as the primary server.
CentOS 7 normally has GLIBC 2.17, while Amazon Linux 2 normally has an older GLIBC than 2.28. Replacing GLIBC in place is risky and is not recommended. Use the legacy Node.js build described later in this post instead.
3. Back Up Cronicle
The Node.js upgrade does not modify Cronicle's data, but taking a backup before maintenance is always a good idea. On the primary server, export Cronicle's vital records:
If your storage configuration uses local files, also make sure your normal filesystem backup is current. Users of S3, Couchbase, or another external storage system should follow the normal backup procedure for that system.
4. Schedule a Maintenance Window
The Node.js installation itself is usually quick, but allow time to verify command paths and restart Cronicle. For clusters, plan to update every server and avoid leaving the cluster on mixed Node.js or Cronicle versions for an extended period.
Upgrade Path A: Current Linux Systems
If getconf GNU_LIBC_VERSION reports GLIBC 2.28 or later, the simplest option is to install Node.js using your operating system's normal package manager, such as yum, dnf, or apt. Make sure the repository you use actually provides Node.js v22, then verify the installed version with node -v.
My personal favorite, and what I use on all of my servers, is NodeSource. NodeSource provides convenient Node.js v22 repositories for current Red Hat and Debian based Linux distributions, and installs using your own OS package manager.
Run the appropriate commands below as root, or add sudo where needed.
Red Hat Based Systems
This includes current versions of RHEL, Rocky Linux, AlmaLinux, Fedora, and Amazon Linux 2023:
The reported Node.js version must be v22.12.0 or later.
Before installing, consider how your old Node.js version was installed. If it came from a different package repository, nvm, or a manual binary installation, the new package may coexist with it instead of replacing it. You may need to remove the old installation using the same tool that installed it, or confirm that your package-manager upgrade replaces it cleanly.
After installation, check for multiple copies and make sure the expected version is selected:
type -a node
command -v node
node -v
npm -v
Cronicle's service or boot script must find the same Node.js v22 executable that your interactive shell finds. If these commands still report an older version, resolve that duplicate installation or PATH issue before upgrading Cronicle.
Upgrade Path B: CentOS 7, Amazon Linux 2, and Other Legacy x86_64 Systems
The official Node.js v22 Linux x64 binary is built for GLIBC 2.28 or later. On an older system, it may fail immediately with messages such as:
version `GLIBC_2.28' not found
version `GLIBCXX_3.4.25' not found
Please do not attempt to replace the system GLIBC just to make Node.js start. GLIBC is a foundational operating system component, and replacing it can break the entire server.
For legacy x86_64 Linux systems, the Node.js project hosts a community-maintained unofficial builds project. Its linux-x64-glibc-217 build targets GLIBC 2.17 and is intended for older distributions and appliances.
First, verify that the machine is x86_64:
uname -m
The result must be x86_64 for the following build. Do not install an x64 binary on an ARM64 or AWS Graviton server.
Download and inspect the unofficial project's installation helper:
curl -fsSL https://unofficial-builds.nodejs.org/install-node.sh -o /tmp/install-node.sh
less /tmp/install-node.sh
After reviewing it, install the newest Node.js v22 build compiled for GLIBC 2.17:
The helper resolves the newest available v22 release, downloads the linux-x64-glibc-217 archive, verifies it against the published SHA-256 checksum, and installs it under /usr/local.
Refresh your shell and verify the result:
export PATH="/usr/local/bin:$PATH"hash -r
type -a node
node --version
npm --version
The unofficial-builds project is community-maintained and describes its output as experimental with minimal testing. It is a valuable compatibility option, but it does not make an end-of-life operating system officially supported by Node.js. Please treat this as a bridge and plan an operating system upgrade or server migration when practical.
If you are running a legacy ARM64 or AWS Graviton system, the x64 GLIBC 2.17 build will not work. The safest choices are to move Cronicle to a newer operating system, move it to a supported x86_64 host, or build Node.js yourself using a suitable toolchain. Please ask in the Cronicle community before attempting an in-place GLIBC replacement.
Verify That Cronicle Will Use the New Node.js
It is possible for an interactive shell to find one Node.js binary while a service or startup script finds another. Before upgrading Cronicle, check all matching commands:
type -a node
command -v node
node --version
You can also verify the Node.js feature needed by the updated sanitize-html dependency:
node -p "process.features.require_module"
This should print true.
Finally, test loading the sanitizer from the Cronicle directory:
cd /opt/cronicle
node -e "require('sanitize-html'); console.log('sanitize-html loaded successfully')"
If this succeeds, the Node.js module loader can load the updated dependency chain.
If /usr/local/bin/node is new but plain node --version still reports an older release, your PATH is selecting another installation first. Do not blindly overwrite an operating-system-managed /usr/bin/node. Either upgrade or remove the old package using the package manager that installed it, or update the Cronicle service environment so /usr/local/bin appears first.
Upgrade Cronicle After Node.js Is Ready
Once every server reports Node.js v22.12.0 or later, upgrade Cronicle normally.
sudo /opt/cronicle/bin/control.sh upgrade
If your Node.js installation lives somewhere else, such as an nvm directory, adjust PATH accordingly. Make the same environment available to whatever starts Cronicle after a reboot.
For a multi-server cluster, repeat the Node.js and Cronicle upgrade on every server. Verify that each server returns to the cluster before moving to the next one.
Troubleshooting
ERR_REQUIRE_ESM Still Appears
Cronicle is still being launched by Node.js v18, v20, or an early v22 release. Check the actual executable and version:
type -a node
readlink -f "$(command -v node)"
node --version
Also inspect the environment used by your system service, cron, rc.local, or other boot mechanism. A successful test in your login shell does not guarantee that a background service has the same PATH.
GLIBC_2.28 Not Found
You installed an official Node.js binary on an older Linux system. On x86_64, use the linux-x64-glibc-217 instructions above. On another architecture, migrate to a newer operating system or use a compatible self-built Node.js release.
node and npm may be coming from different installations. Ensure both commands resolve through the same Node.js v22 installation.
Cronicle Starts Manually but Not After Reboot
Your boot-time service probably has a different PATH. Make sure the service environment includes the directory containing the new node executable, typically /usr/local/bin, before /usr/bin and /bin.
If You Cannot Upgrade Immediately
You may remain on Cronicle v0.9.126 or earlier while you plan the operating system and Node.js work. It will not stop running merely because a newer Cronicle version exists. If you already installed v0.9.127 or v0.9.128 and cannot start Cronicle, either complete the Node.js upgrade or temporarily return to v0.9.126 while planning the maintenance.
An emergency downgrade can be performed with:
sudo /opt/cronicle/bin/control.sh upgrade 0.9.126
This is only a temporary compatibility measure. It restores older dependency versions that do not contain all of the latest security fixes.
However, older Cronicle releases also retain their older dependency versions. For that reason, staying back should be considered a temporary measure rather than a permanent solution. Please restrict access appropriately, keep reliable backups, and plan the upgrade as soon as reasonably possible.
Thank You
I know this is a substantial requirement change, and I am sorry for the disruption it may cause. Cronicle has always tried to remain friendly to modest and older servers, so raising the runtime floor is not something I take lightly.
At the same time, keeping Cronicle secure has to take priority. Continuing to ship an old sanitizer, or pretending that a tiny project can safely replace an entire dependency ecosystem, would not serve the community well.
If you run into trouble, please reply to this discussion with the following information:
Operating system and version:
CPU architecture from uname -m:
GLIBC version from getconf GNU_LIBC_VERSION:
Node.js version from node --version:
Node.js path from command -v node:
npm version from npm --version:
Cronicle version:
Complete error message:
Thank you for your patience, for keeping your installations secure, and for continuing to use Cronicle.
Also, huge thank you to user @solemnwarning for bringing this issue to my attention!
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Hello everyone,
I need to announce an upcoming breaking change that I know will inconvenience some Cronicle users, especially those who have been running stable installations for many years.
Starting with Cronicle v0.9.127, Cronicle requires Node.js v22.12.0 or later. Please note the full version number. Node.js v22.0 through v22.11 will not be sufficient.
This requirement arrived indirectly with an urgent dependency update in v0.9.127, which is why users on older Node.js releases currently see a confusing
ERR_REQUIRE_ESMmessage rather than a clear version warning. The next Cronicle patch release will add an explicit installer and startup check so the requirement is communicated properly.I am genuinely sorry to impose this upgrade. I know that a runtime upgrade can turn an otherwise routine Cronicle update into real maintenance work. This is particularly difficult for people running CentOS 7, Amazon Linux 2, older NAS devices, and other systems whose C libraries are too old for the official Node.js v22 Linux binaries.
This was not a casual decision. The change is being forced by security updates in Cronicle's dependency chain. This post explains what changed, why we cannot safely avoid it, and how to upgrade on both current and legacy Linux systems.
Short Version
linux-x64-glibc-217Node.js build described below.Why This Is Necessary
Cronicle uses
sanitize-htmlto protect custom HTML job reports against cross-site scripting and related attacks. Recentsanitize-htmlreleases corrected multiple sanitizer bypasses. Some of these fixes required an upgrade tohtmlparser2v12 so that the sanitizer and a real browser agree about how certain unusual combinations of HTML, SVG, MathML, and raw-text elements are parsed.That upgrade introduced an unavoidable runtime requirement:
sanitize-htmlis a CommonJS module.htmlparser2v12 and its related packages are ECMAScript modules.sanitize-htmlmust loadhtmlparser2synchronously to preserve its existing synchronous API.sanitize-htmlnow explicitly requires Node.js>=22.12.0.The
sanitize-htmlv2.17.6 changelog explains both the security fixes and the resulting Node.js requirement. The underlying Node.js behavior is documented under Loading ECMAScript modules usingrequire().On Node.js v18, Cronicle fails during startup with an error similar to this:
This error is independent of Debian, CentOS, Amazon Linux, or macOS. The operating system only becomes relevant when attempting to install a sufficiently new Node.js binary.
Between a Rock and a Hard Place
As maintainers, we effectively have three choices:
The first choice is not responsible for software that receives and displays user-controlled data. The second is not realistic for a small open source project. Cronicle simply does not have the manpower to replace and continuously security-audit mature projects such as
sanitize-html,htmlparser2, and all of their supporting packages.That leaves the third choice. We are upgrading the dependencies so Cronicle receives the security fixes, but doing so forces us to raise Cronicle's Node.js floor to v22.12.0.
I do not like requiring users to upgrade a working runtime, but shipping a scheduler with known, preventable security weaknesses would be worse. I am truly sorry for the extra work required to keep Cronicle running and up to date.
Who Needs to Take Action?
Run these commands on every Cronicle server, including workers and backup-primary servers:
node --version npm --version command -v nodeUse the following table to determine what you need to do:
I recommend installing the newest available patch release in the Node.js v22 LTS line rather than installing exactly v22.12.0. Newer patch releases include additional bug and security fixes.
Before You Upgrade
Please take a few minutes to inventory and back up your installation first.
1. Check Every Server
For a multi-server Cronicle cluster, repeat the version checks on every machine. Do not assume that all workers have the same Node.js version as the primary server.
hostname node --version npm --version command -v node2. Check Your Linux Architecture and GLIBC Version
A typical current x86_64 server might report:
The official Node.js Linux binaries require GLIBC 2.28 or later. This is documented in the Node.js supported platforms and official binary requirements.
CentOS 7 normally has GLIBC 2.17, while Amazon Linux 2 normally has an older GLIBC than 2.28. Replacing GLIBC in place is risky and is not recommended. Use the legacy Node.js build described later in this post instead.
3. Back Up Cronicle
The Node.js upgrade does not modify Cronicle's data, but taking a backup before maintenance is always a good idea. On the primary server, export Cronicle's vital records:
sudo /opt/cronicle/bin/control.sh export /root/cronicle-before-node22.txt --verbose sudo cp /opt/cronicle/conf/config.json /root/cronicle-config-before-node22.jsonIf your storage configuration uses local files, also make sure your normal filesystem backup is current. Users of S3, Couchbase, or another external storage system should follow the normal backup procedure for that system.
4. Schedule a Maintenance Window
The Node.js installation itself is usually quick, but allow time to verify command paths and restart Cronicle. For clusters, plan to update every server and avoid leaving the cluster on mixed Node.js or Cronicle versions for an extended period.
Upgrade Path A: Current Linux Systems
If
getconf GNU_LIBC_VERSIONreports GLIBC 2.28 or later, the simplest option is to install Node.js using your operating system's normal package manager, such asyum,dnf, orapt. Make sure the repository you use actually provides Node.js v22, then verify the installed version withnode -v.My personal favorite, and what I use on all of my servers, is NodeSource. NodeSource provides convenient Node.js v22 repositories for current Red Hat and Debian based Linux distributions, and installs using your own OS package manager.
Run the appropriate commands below as
root, or addsudowhere needed.Red Hat Based Systems
This includes current versions of RHEL, Rocky Linux, AlmaLinux, Fedora, and Amazon Linux 2023:
curl -fsSL https://rpm.nodesource.com/setup_22.x | bash - dnf install nodejs -y node -vIf your system uses
yuminstead ofdnf, useyum install nodejs -yon the second line.Debian Based Systems
This includes current versions of Debian and Ubuntu:
curl -fsSL https://deb.nodesource.com/setup_22.x | bash - apt-get install -y nodejs node -vThe reported Node.js version must be v22.12.0 or later.
Before installing, consider how your old Node.js version was installed. If it came from a different package repository,
nvm, or a manual binary installation, the new package may coexist with it instead of replacing it. You may need to remove the old installation using the same tool that installed it, or confirm that your package-manager upgrade replaces it cleanly.After installation, check for multiple copies and make sure the expected version is selected:
Cronicle's service or boot script must find the same Node.js v22 executable that your interactive shell finds. If these commands still report an older version, resolve that duplicate installation or
PATHissue before upgrading Cronicle.Upgrade Path B: CentOS 7, Amazon Linux 2, and Other Legacy x86_64 Systems
The official Node.js v22 Linux x64 binary is built for GLIBC 2.28 or later. On an older system, it may fail immediately with messages such as:
Please do not attempt to replace the system GLIBC just to make Node.js start. GLIBC is a foundational operating system component, and replacing it can break the entire server.
For legacy x86_64 Linux systems, the Node.js project hosts a community-maintained unofficial builds project. Its
linux-x64-glibc-217build targets GLIBC 2.17 and is intended for older distributions and appliances.First, verify that the machine is x86_64:
The result must be
x86_64for the following build. Do not install an x64 binary on an ARM64 or AWS Graviton server.Download and inspect the unofficial project's installation helper:
After reviewing it, install the newest Node.js v22 build compiled for GLIBC 2.17:
The helper resolves the newest available v22 release, downloads the
linux-x64-glibc-217archive, verifies it against the published SHA-256 checksum, and installs it under/usr/local.Refresh your shell and verify the result:
The
unofficial-buildsproject is community-maintained and describes its output as experimental with minimal testing. It is a valuable compatibility option, but it does not make an end-of-life operating system officially supported by Node.js. Please treat this as a bridge and plan an operating system upgrade or server migration when practical.If you are running a legacy ARM64 or AWS Graviton system, the x64 GLIBC 2.17 build will not work. The safest choices are to move Cronicle to a newer operating system, move it to a supported x86_64 host, or build Node.js yourself using a suitable toolchain. Please ask in the Cronicle community before attempting an in-place GLIBC replacement.
Verify That Cronicle Will Use the New Node.js
It is possible for an interactive shell to find one Node.js binary while a service or startup script finds another. Before upgrading Cronicle, check all matching commands:
You can also verify the Node.js feature needed by the updated sanitize-html dependency:
node -p "process.features.require_module"This should print
true.Finally, test loading the sanitizer from the Cronicle directory:
If this succeeds, the Node.js module loader can load the updated dependency chain.
If
/usr/local/bin/nodeis new but plainnode --versionstill reports an older release, yourPATHis selecting another installation first. Do not blindly overwrite an operating-system-managed/usr/bin/node. Either upgrade or remove the old package using the package manager that installed it, or update the Cronicle service environment so/usr/local/binappears first.Upgrade Cronicle After Node.js Is Ready
Once every server reports Node.js v22.12.0 or later, upgrade Cronicle normally.
If your Node.js installation lives somewhere else, such as an
nvmdirectory, adjustPATHaccordingly. Make the same environment available to whatever starts Cronicle after a reboot.For a multi-server cluster, repeat the Node.js and Cronicle upgrade on every server. Verify that each server returns to the cluster before moving to the next one.
Troubleshooting
ERR_REQUIRE_ESMStill AppearsCronicle is still being launched by Node.js v18, v20, or an early v22 release. Check the actual executable and version:
Also inspect the environment used by your system service,
cron,rc.local, or other boot mechanism. A successful test in your login shell does not guarantee that a background service has the samePATH.GLIBC_2.28 Not FoundYou installed an official Node.js binary on an older Linux system. On x86_64, use the
linux-x64-glibc-217instructions above. On another architecture, migrate to a newer operating system or use a compatible self-built Node.js release.npm Reports an Unsupported Engine
Run:
nodeandnpmmay be coming from different installations. Ensure both commands resolve through the same Node.js v22 installation.Cronicle Starts Manually but Not After Reboot
Your boot-time service probably has a different
PATH. Make sure the service environment includes the directory containing the newnodeexecutable, typically/usr/local/bin, before/usr/binand/bin.If You Cannot Upgrade Immediately
You may remain on Cronicle v0.9.126 or earlier while you plan the operating system and Node.js work. It will not stop running merely because a newer Cronicle version exists. If you already installed v0.9.127 or v0.9.128 and cannot start Cronicle, either complete the Node.js upgrade or temporarily return to v0.9.126 while planning the maintenance.
An emergency downgrade can be performed with:
This is only a temporary compatibility measure. It restores older dependency versions that do not contain all of the latest security fixes.
However, older Cronicle releases also retain their older dependency versions. For that reason, staying back should be considered a temporary measure rather than a permanent solution. Please restrict access appropriately, keep reliable backups, and plan the upgrade as soon as reasonably possible.
Thank You
I know this is a substantial requirement change, and I am sorry for the disruption it may cause. Cronicle has always tried to remain friendly to modest and older servers, so raising the runtime floor is not something I take lightly.
At the same time, keeping Cronicle secure has to take priority. Continuing to ship an old sanitizer, or pretending that a tiny project can safely replace an entire dependency ecosystem, would not serve the community well.
If you run into trouble, please reply to this discussion with the following information:
Thank you for your patience, for keeping your installations secure, and for continuing to use Cronicle.
Also, huge thank you to user @solemnwarning for bringing this issue to my attention!
All reactions