diff --git a/gitlab-ci-config/gitlab-com.yml b/gitlab-ci-config/gitlab-com.yml
index 9e444ffe83b1fc73763c3dc10cfc89d32ded9f53_Z2l0bGFiLWNpLWNvbmZpZy9naXRsYWItY29tLnltbA==..cf70b938a90df3a1cb11cffee34d888e671bb2a5_Z2l0bGFiLWNpLWNvbmZpZy9naXRsYWItY29tLnltbA== 100644
--- a/gitlab-ci-config/gitlab-com.yml
+++ b/gitlab-ci-config/gitlab-com.yml
@@ -638,6 +638,22 @@
   rules:
     - if: '$PIPELINE_TYPE == "DEPS_IO_VERSION_CHECK_PIPELINE"'
 
+validate_renovate_checksum:
+  image: docker.io/bash:5.2-alpine3.20
+  stage: prepare
+  before_script:
+    - apk add git
+  script:
+    - ./scripts/renovate/checksums/update_all.sh
+    - mismatches="$(git status --porcelain)"
+    - if [ -n "$mismatches" ]; then
+        echo "Checksum mismatch detected"; 
+        echo "$mismatches"; 
+        exit 1; 
+      fi
+  rules:
+    - if: '$PIPELINE_TYPE == "GITLAB_MR_PIPELINE"'
+
 validate_packer_changes:
   before_script: []
   image: "${PUBLIC_BUILDER_IMAGE_REGISTRY}/debian_packer:${BUILDER_IMAGE_REVISION}"
diff --git a/scripts/renovate/checksums/software/libxml2.sh b/scripts/renovate/checksums/software/libxml2.sh
new file mode 100755
index 0000000000000000000000000000000000000000..cf70b938a90df3a1cb11cffee34d888e671bb2a5_c2NyaXB0cy9yZW5vdmF0ZS9jaGVja3N1bXMvc29mdHdhcmUvbGlieG1sMi5zaA==
--- /dev/null
+++ b/scripts/renovate/checksums/software/libxml2.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+# Fetch and replace the libxml2 checksum.
+# Dependencies: curl, sed, awk
+
+set -eo pipefail
+
+libxml2_build_file="config/software/libxml2.rb"
+
+get_target_version() {
+  sed -nr "s|default_version '(.*)'|\1|p" "$libxml2_build_file"
+}
+
+get_checksum() {
+  local version="$1"
+  local minor_version=$(sed -nr 's|(\w*).(\w*).(\w*)|\1.\2|p' <<< "$version")
+
+  local checksum_file_url="https://download.gnome.org/sources/libxml2/${minor_version}/libxml2-${version}.sha256sum"
+  local archive_name="libxml2-${version}.tar.xz"
+
+  wget -q -O - "$checksum_file_url" | awk -v file="$archive_name" '{if($2==file){print $1}}'
+}
+
+replace_checksum() {
+  local new_checksum="$1"
+  local libxml2_build_file="config/software/libxml2.rb"
+
+  sed -i "s|sha256: '\w*'|sha256: '${new_checksum}'|" "$libxml2_build_file"
+}
+
+version=$(get_target_version)
+checksum=$(get_checksum "$version")
+replace_checksum "$checksum"
diff --git a/scripts/renovate/checksums/update_all.sh b/scripts/renovate/checksums/update_all.sh
new file mode 100755
index 0000000000000000000000000000000000000000..cf70b938a90df3a1cb11cffee34d888e671bb2a5_c2NyaXB0cy9yZW5vdmF0ZS9jaGVja3N1bXMvdXBkYXRlX2FsbC5zaA==
--- /dev/null
+++ b/scripts/renovate/checksums/update_all.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+#
+# Update all checksums managed by renovate.
+
+SCRIPT_DIR=$(dirname "$0")
+
+for checksum_script in "${SCRIPT_DIR}"/software/*.sh; do
+  echo "Running ${checksum_script}"
+  ./"${checksum_script}"
+done