Skip to main content
NageshRaja
Level 5
September 9, 2026
Question

Discrepancy in Dispatcher Validator - Local vs Pipeline

  • September 9, 2026
  • 5 replies
  • 82 views

Hi All,

 

I ran the dispatcher utility in local and it auto-runs as part of web-tier in build stage too.

Ideally one would expect same inconsistencies but there was a difference in my case.

 

Local Validator - 

PS C:\Users\admin\Downloads\aem-sdk-dispatcher-tools-2.0.274-windows\bin> .\validate.cmd 'C:\projA\dispatcher\src'
opt-in USE_SOURCES_DIRECTLY marker file detected
Phase 1: Dispatcher validator
Cloud manager validator 2.0.89
2026/09/07 19:41:48 The following warnings were found:
Did not find ServerAlias '*.adobeaemcloud.net' in any vhost file
Did not find ServerAlias '*.adobeaemcloud.com' in any vhost file

2026/09/07 19:41:48 The following suggestions are proposed:
C:\projA\dispatcher\src\conf.d\enabled_vhosts\aem_publish.vhost: file is not a symlink, all files inside "enabled_vhosts" and "enabled_farms" should be symlinks

2026/09/08 19:41:48 The following errors were found in the httpd config:
C:\projA\dispatcher\src\conf.d\enabled_vhosts\aem_publish.vhost: link points to invalid location: C:/projA/dispatcher/src/conf.d/available_vhosts/aem_publish.vhost, CreateFile C:\projA\dispatcher\src\conf.d\enabled_vhosts\C:\projA\dispatcher\src\conf.d\available_vhosts\aem_publish.vhost: The filename, directory name, or volume label syntax is incorrect.

2026/09/07 19:41:48 skipping symlinks resolution checks for global folder due to windows platform
2026/09/07 19:41:48 please use a Linux/OS X environment to run locally or check results with a Cloud Manager pipeline
Phase 1 failed

Primary Error on Local - “symLinks resolution”

Cloud Validator - 

Log file: dispatcher_validation.log
STATUS_SIGNAL: /mnt/shared/status-validation
Waiting max 600 seconds for the build zip file
Timeout: 600s
Running [runValidation]...
End stage: start
Begin stage: prepare configuration
step1: prepare destination directories
step2: extract layer0
step3: waiting for customer zip file
Iteration: 0/600. Waiting for customer zip file...
Iteration: 16/600. Waiting for customer zip file...
There are zip files, using /mnt/shared/dispatcher.zip
Extracting: /mnt/shared/dispatcher.zip
step4: extract layer1 (customer configuration)
End stage: prepare configuration
Begin stage: check configuration
10 biggest configuration files:
24094  04-09-26 12:00  /tmp/dispatcher/unzippedConfiguration/conf.d/available_vhosts/brandA.vhost
13417  04-09-26 12:00  /tmp/dispatcher/unzippedConfiguration/conf.d/dispatcher_vhost.conf
12008  04-09-26 12:00  /tmp/dispatcher/unzippedConfiguration/conf/httpd.conf
10051  04-09-26 12:00  /tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/filters/brandA_filters.any
total size of unpacked dispatcher configuration:
656K  /tmp/dispatcher/unzippedConfiguration
opt-in USE_SOURCES_DIRECTLY marker file detected
immutability check (warns in case of mutation detection):
checking 'conf.d/available_vhosts/default.vhost' immutability (if present)
checking existing 'conf.d/available_vhosts/default.vhost' for changes
checking 'conf.d/dispatcher_vhost.conf' immutability (if present)
replacing include directive in 'conf.d/dispatcher_vhost.conf' before comparing
checking existing 'conf.d/dispatcher_vhost.conf' for changes
!! immutable file 'conf.d/dispatcher_vhost.conf' has been changed!
!! diff output:
--- /etc/httpd-expected/conf.d/dispatcher_vhost.conf
+++ /tmp/dispatcher/unzippedConfiguration/conf.d/dispatcher_vhost.conf
@@ -317,7 +317,7 @@
</VirtualHost>

# Customer's vhosts:
-Include "conf.d/enabled_vhosts/*.vhost"
+Include conf.d/enabled_vhosts/vhosts.conf

# Create a catch-all vhost
# A catch-all is a safe place for un-matched hostnames to land.
!!
checking 'conf.d/enabled_vhosts/vhosts.conf' immutability (if present)
checking existing 'conf.d/enabled_vhosts/vhosts.conf' for changes
checking 'conf.d/rewrites/default_rewrite.rules' immutability (if present)
checking existing 'conf.d/rewrites/default_rewrite.rules' for changes
checking 'conf.dispatcher.d/available_farms/default.farm' immutability (if present)
checking existing 'conf.dispatcher.d/available_farms/default.farm' for changes
checking 'conf.dispatcher.d/cache/default_invalidate.any' immutability (if present)
replacing 'conf.dispatcher.d/cache/default_invalidate.any' content as it gets overridden on startup anyway
'/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/cache/default_invalidate.any' -> '/etc/httpd-expected/conf.dispatcher.d/cache/default_invalidate.any'
checking existing 'conf.dispatcher.d/cache/default_invalidate.any' for changes
checking 'conf.dispatcher.d/cache/default_rules.any' immutability (if present)
checking existing 'conf.dispatcher.d/cache/default_rules.any' for changes
checking 'conf.dispatcher.d/clientheaders/default_clientheaders.any' immutability (if present)
checking existing 'conf.dispatcher.d/clientheaders/default_clientheaders.any' for changes
!! immutable file 'conf.dispatcher.d/clientheaders/default_clientheaders.any' has been changed!
!! diff output:
--- /etc/httpd-expected/conf.dispatcher.d/clientheaders/default_clientheaders.any
+++ /tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/clientheaders/default_clientheaders.any
@@ -4,7 +4,7 @@
# DO NOT EDIT this file, your changes will have no impact on your deployment.
#
# Instead modify clientheaders.any.
-#
+# host removed from below list

"X-Forwarded-Proto"
"X-Forwarded-SSL-Certificate"
@@ -21,7 +21,6 @@
"accept-encoding"
"accept-language"
"accept"
-"host"
"if-match"
"if-none-match"
"if-range"
!!
checking 'conf.dispatcher.d/dispatcher.any' immutability (if present)
replacing include directive in 'conf.dispatcher.d/dispatcher.any' before comparing
checking existing 'conf.dispatcher.d/dispatcher.any' for changes
!! immutable file 'conf.dispatcher.d/dispatcher.any' has been changed!
!! diff output:
--- /etc/httpd-expected/conf.dispatcher.d/dispatcher.any
+++ /tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/dispatcher.any
@@ -1,11 +1,10 @@
-#
-# This is a file provided by the runtime environment and only included for
-# illustration purposes.
-#
-# DO NOT EDIT this file, your changes will have no impact on your deployment.
-#
+### Name of the dispatcher
+/name "internet-server"

+## each farm configures a set of (load-balanced) renders
+### Include the author first on purpose
+### Include the publish farm last. That way if the hostname isn't matched they'll end up on the last farm, better for 404 errors that are non descript than 403 authentication and redirect to a login page
+
/farms {
-  # Include all *.farm files in enabled_farms
-  $include "enabled_farms/*.farm"
+  $include "enabled_farms/*_farm.any"
}
!!
checking 'conf.dispatcher.d/enabled_farms/farms.any' immutability (if present)
checking existing 'conf.dispatcher.d/enabled_farms/farms.any' for changes
checking 'conf.dispatcher.d/filters/default_filters.any' immutability (if present)
checking existing 'conf.dispatcher.d/filters/default_filters.any' for changes
checking 'conf.dispatcher.d/renders/default_renders.any' immutability (if present)
checking existing 'conf.dispatcher.d/renders/default_renders.any' for changes
checking 'conf.dispatcher.d/virtualhosts/default_virtualhosts.any' immutability (if present)
checking existing 'conf.dispatcher.d/virtualhosts/default_virtualhosts.any' for changes
!!
!! Mutation of immutable files was detected - these changes will be overwritten at runtime!
!!
overwriting immutable file 'conf.d/available_vhosts/default.vhost'
'/etc/httpd/conf.d/available_vhosts/default.vhost' -> '/tmp/dispatcher/unzippedConfiguration/conf.d/available_vhosts/default.vhost'
overwriting immutable file 'conf.d/dispatcher_vhost.conf'
'/etc/httpd/conf.d/dispatcher_vhost.conf' -> '/tmp/dispatcher/unzippedConfiguration/conf.d/dispatcher_vhost.conf'
overwriting immutable file 'conf.d/enabled_vhosts/vhosts.conf'
'/etc/httpd/conf.d/enabled_vhosts/vhosts.conf' -> '/tmp/dispatcher/unzippedConfiguration/conf.d/enabled_vhosts/vhosts.conf'
overwriting immutable file 'conf.d/rewrites/default_rewrite.rules'
'/etc/httpd/conf.d/rewrites/default_rewrite.rules' -> '/tmp/dispatcher/unzippedConfiguration/conf.d/rewrites/default_rewrite.rules'
overwriting immutable file 'conf.dispatcher.d/available_farms/default.farm'
'/etc/httpd/conf.dispatcher.d/available_farms/default.farm' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/available_farms/default.farm'
overwriting immutable file 'conf.dispatcher.d/cache/default_invalidate.any'
'/etc/httpd/conf.dispatcher.d/cache/default_invalidate.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/cache/default_invalidate.any'
overwriting immutable file 'conf.dispatcher.d/cache/default_rules.any'
'/etc/httpd/conf.dispatcher.d/cache/default_rules.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/cache/default_rules.any'
overwriting immutable file 'conf.dispatcher.d/clientheaders/default_clientheaders.any'
'/etc/httpd/conf.dispatcher.d/clientheaders/default_clientheaders.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/clientheaders/default_clientheaders.any'
overwriting immutable file 'conf.dispatcher.d/dispatcher.any'
'/etc/httpd/conf.dispatcher.d/dispatcher.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/dispatcher.any'
overwriting immutable file 'conf.dispatcher.d/enabled_farms/farms.any'
'/etc/httpd/conf.dispatcher.d/enabled_farms/farms.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/enabled_farms/farms.any'
overwriting immutable file 'conf.dispatcher.d/filters/default_filters.any'
'/etc/httpd/conf.dispatcher.d/filters/default_filters.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/filters/default_filters.any'
overwriting immutable file 'conf.dispatcher.d/renders/default_renders.any'
'/etc/httpd/conf.dispatcher.d/renders/default_renders.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/renders/default_renders.any'
overwriting immutable file 'conf.dispatcher.d/virtualhosts/default_virtualhosts.any'
'/etc/httpd/conf.dispatcher.d/virtualhosts/default_virtualhosts.any' -> '/tmp/dispatcher/unzippedConfiguration/conf.dispatcher.d/virtualhosts/default_virtualhosts.any'
Cloud manager validator 2.0.89
2026/09/04 12:00:44 Dispatcher configuration validation failed:
2026/09/04 12:00:44 conf.dispatcher.d/clientheaders/default_clientheaders.any:24: duplicate client header: host
conf.dispatcher.d/clientheaders/default_clientheaders.any:24: duplicate client header: host

ERROR: '11 TEST_FAILURE dispatcher validator failed'
at validate_configuration(/usr/local/bin/validate-static.sh:127)
at runValidation(/usr/local/bin/validate-static.sh:189)
at status.track(/usr/local/bin/lib-status.bash:261)
at main(/usr/local/bin/validate-static.sh:192)
Reporting error to: '/mnt/shared/status-validation'
ERROR: '11 TEST_FAILURE ERROR: '11 TEST_FAILURE dispatcher validator failed'
at validate_configuration(/usr/local/bin/validate-static.sh:127)
at runValidation(/usr/local/bin/validate-static.sh:189)
at status.track(/usr/local/bin/lib-status.bash:261)
at main(/usr/local/bin/validate-static.sh:192)'
at reportError(/usr/local/bin/lib-status.bash:127)
at validate_configuration(/usr/local/bin/validate-static.sh:127)
at runValidation(/usr/local/bin/validate-static.sh:189)
at status.track(/usr/local/bin/lib-status.bash:261)
at main(/usr/local/bin/validate-static.sh:192)
Status file exists: '/mnt/shared/status-validation' assuming it is already saved in earlier step.
ERROR: '11 SCRIPT_ERROR Script command failed (see stack trace)'
at status.internal.handleError(/usr/local/bin/lib-status.bash:269)
at status.track(/usr/local/bin/lib-status.bash:269)
at main(/usr/local/bin/validate-static.sh:192)
Status file exists: '/mnt/shared/status-validation' assuming it is already saved in earlier step.
at status.internal.handleExit(/usr/local/bin/lib-status.bash:56) exited with code '11'

Primary Error on Cloud - “duplicate client header: host”

More importantly the error flagged in cloud pipeline is not reported on local. Is that to be expected?

 

Thanks,
NK

5 replies

shrutid56001193
User Group Leader
User Group Leader
September 10, 2026

​@NageshRaja 

I think these are actually two separate issues.

Your local validation is failing early because you're running it on Windows and the Dispatcher config uses symlinks. Because of that, it doesn't get far enough to catch the same issue as the Cloud Manager pipeline.

The pipeline is pointing to the actual config issue:

duplicate client header: host

I would check clientheaders.any and default_clientheaders.any for a duplicate "host" entry. Also, the pipeline log shows that some immutable Dispatcher files have been modified, so restoring those to the SDK defaults and keeping customisations in the appropriate custom files might help.

https://www.shrutidamle.com/
NageshRaja
Level 5
September 10, 2026

I did fix the dispatcher validator error for “duplicate client header: host” issue.
The web-tier pipeline is running fine. But the local cloud validator still gives the issue.
Same happens if I use WSL too. How can I bypass this issue on local?

shrutid56001193
User Group Leader
User Group Leader
September 10, 2026

​@NageshRaja Probably the reason it won't pass locally is that the Windows validate.cmd can't resolve symlinks at all — that's the "please use a Linux/OS X environment" line. When you say it also fails in WSL, it could be one of three things:

  • you're still calling validate.cmd (the Windows binary) from WSL instead of the Linux validate.sh — the Windows one behaves the same wherever you launch it;
  • the committed symlink points at an absolute path (C:/projA/.../available_vhosts/aem_publish.vhost), which is what produces that doubled path in your error. It needs to be the relative ../available_vhosts/aem_publish.vhost;
  • core.symlinks is false in Git, so it checked the link out as a plain file — that's why you see "file is not a symlink" and "invalid location" together.

Try to recreate it as a real relative symlink and validate with the Linux validate.sh 

https://www.shrutidamle.com/
Raja_Reddy
Community Advisor
Community Advisor
September 10, 2026

Hi ​@NageshRaja 

The difference is expected. The local validator (Windows) failed during symlink resolution and stopped before completing all validation checks. Cloud Manager runs on Linux, so it was able to continue further and identify the actual issue: duplicate client header: host.

https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/local-development-environment-set-up/dispatcher-tools

https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/content-delivery/validation-debug 
 

AmitVishwakarma
Community Advisor
Community Advisor
September 16, 2026

Hi ​@NageshRaja 
The local and Cloud Manager results are different because the local validation is running on Windows, while Cloud Manager validates the Dispatcher configuration in a Linux environment.

There are two fixes required.
1. Recreate the symlink correctly

The symlink must be a real relative symlink. Do not use an absolute Windows path such as:

C:/projA/dispatcher/src/conf.d/available_vhosts/aem_publish.vhost

From Linux, macOS, or WSL, run:

cd dispatcher/src/conf.d/enabled_vhosts
rm -f aem_publish.vhost
ln -s ../available_vhosts/aem_publish.vhost aem_publish.vhost

For farm files, use the same pattern:

cd dispatcher/src/conf.dispatcher.d/enabled_farms
rm -f <farm-file>
ln -s ../available_farms/<farm-file> <farm-file>

Check that Git has stored the link as a symlink:

git ls-files -s dispatcher/src/conf.d/enabled_vhosts/aem_publish.vhost
readlink dispatcher/src/conf.d/enabled_vhosts/aem_publish.vhost

The Git mode should be 120000, and the target should be:

../available_vhosts/aem_publish.vhost

It is better to clone the repository inside the WSL/Linux filesystem, for example under ~/work, instead of /mnt/c/.…

2. Restore dispatcher_vhost.conf

The Cloud Manager log shows that an immutable Adobe file was changed:

-Include "conf.d/enabled_vhosts/*.vhost"
+Include conf.d/enabled_vhosts/vhosts.conf

Restore dispatcher/src/conf.d/dispatcher_vhost.conf from the Dispatcher SDK that matches your AEM as a Cloud Service release. Do not modify this file to solve the symlink problem.

Your custom vhost should be placed under: 

conf.d/available_vhosts/

and then enabled with a relative symlink under:

conf.d/enabled_vhosts/

3. Add the required aliases

Add these aliases to the active custom .vhost file, not to dispatcher_vhost.conf:

ServerAlias localhost
ServerAlias 127.0.0.1
ServerAlias *.adobeaemcloud.net
ServerAlias *.adobeaemcloud.com

Finally, run the validator from Linux, macOS, or WSL using the correct Dispatcher SDK:

./bin/validate.sh /path/to/project/dispatcher/src

Commit the changes and push them again. The Windows absolute symlink, the modified immutable file, and the missing aliases must all be corrected before rerunning the Cloud Manager pipeline.

Adobe documents the flexible Dispatcher layout, symlink structure, required aliases, and immutable files in

https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/content-delivery/validation-debug
If the baseline files are outdated, update them using the Dispatcher SDK as described in https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/local-development-environment-set-up/dispatcher-tools

Adobe also confirms that immutable Dispatcher files are not customer-customization points in https://experienceleague.adobe.com/en/docs/experience-manager-cloud-manager/content/using/code-deployment

Amit Vishwakarma - Adobe Commerce Champion 2025 | 17x Adobe certified | 6x Adobe SME