Command
update
Is this a regression?
The previous version in which this bug was not present was
21.1.4
Description
The security patch for GHSA-x288-3778-4hhx introduced a mandatory allowedHosts
configuration for CommonEngine. When it is not configured after upgrading, Angular SSR
silently falls back to client-side rendering — returning a bare <app-root></app-root>
with HTTP 200 and no thrown exception.
Any application upgrading via ng update loses SSR silently with:
- No build error
- No test failure
- No runtime exception
- The page appears fully functional (Angular bootstraps client-side)
The only signal is a console.error to Node.js stdout that is trivially missed,
especially in containerized environments where Node stdout is mixed with other logs.
ng update has no mention of this requirement, and the migration guide is silent about it.
The only documentation is buried in the security guide, far from any upgrade path.
Minimal Reproduction
-
Generate a standard SSR app on a version before the security patch (last unaffected: 21.1.4):
ng new repro --ssr
cd repro
-
Confirm SSR works on the unaffected version:
ng build
node dist/repro/server/server.mjs &
curl -s http://localhost:4000/ | grep -c "app-root><"
# Returns 0 — app-root has content, SSR is working
kill %1
-
Upgrade to a patched version (first affected: 21.1.5):
ng update @angular/cli@21.1.5 @angular/core@21.1.5 @angular/ssr@21.1.5
-
Build and start the SSR server again — no changes to server.ts:
ng build
node dist/repro/server/server.mjs
-
Check the SSR response:
curl -s http://localhost:4000/ | grep -c "app-root><"
# Returns 1 — app-root is empty, SSR silently stopped working
-
Check Node.js stdout — you will see:
ERROR: URL with hostname "localhost" is not allowed. Please provide a list of
allowed hosts in the "allowedHosts" option in the "CommonEngine" constructor.
Falling back to client side rendering. This will become a 400 Bad Request in a future major version.
Note: ng update in step 3 produced no warning or action required message about this.
Fix: add allowedHosts to CommonEngine in server.ts:
const commonEngine = new CommonEngine({
allowedHosts: ['localhost', '*.yourdomain.com'],
});
Verified results
Angular 21.1.4 — SSR works, app-root contains rendered content:
<app-root ng-version="21.1.4" ngh="1">
<p id="before">Before defer (should always be in SSR output)</p>
<app-deferred><p>I am inside the defer block</p></app-deferred>
<p id="after">After defer (should always be in SSR output)</p>
</app-root>
Angular 21.1.5 — SSR silently falls back to CSR after ng update, no changes to server.ts:
ERROR: URL with hostname "localhost" is not allowed.Please provide a list of allowed hosts
in the "allowedHosts" option in the "CommonEngine" constructor.
Falling back to client side rendering. This will become a 400 Bad Request in a future major version.
<app-root></app-root>
ng update produced zero output about this requirement.
Exception or Error
ERROR: URL with hostname "localhost" is not allowed.Please provide a list of allowed hosts
in the "allowedHosts" option in the "CommonEngine" constructor.
Falling back to client side rendering. This will become a 400 Bad Request in a future major version.
Your Environment
Angular CLI: 21.1.5
Angular: 21.1.5
@angular/ssr: 21.1.5
@angular-devkit/build-angular: 21.1.5
Node.js: 20.19.2
Package Manager: npm 10.8.2
OS: darwin arm64
express: 4.22.1
Last working version: @angular/ssr 21.1.4
First broken version: @angular/ssr 21.1.5
Relevant `angular.json` (build options):
"builder": "@angular-devkit/build-angular:application",
"options": {
"server": "src/main.server.ts",
"outputMode": "server",
"ssr": {
"entry": "server.ts"
}
}
Anything else relevant?
- This affects all SSR setups using
CommonEngine
- The affected versions are: >=21.1.5, >=21.2.0-rc.1, >=20.3.17, >=19.2.21 (all patched versions from GHSA-x288-3778-4hhx)
@angular/ssr 21.2.7 does not include an ng-update key in package.json — there are zero update migrations provided. Running ng update (or nx migrate) completes silently with no output related to allowedHosts whatsoever.
- Related issue: #32616 — SSR strict host validation breaks application on cloud platform (closed, different angle — focuses on Kubernetes IP headers, not the missing documentation)
What would help:
-
Migration guide — add a note that allowedHosts must be configured in server.ts after upgrading, with a link to the security guide. The domains are application-specific so no automation is possible, but a clear callout during upgrade would prevent this.
-
ng update warning — print an ACTION REQUIRED message during the update process, similar to how other breaking changes are surfaced. Example:
ACTION REQUIRED: The security patch for GHSA-x288-3778-4hhx requires configuring
allowedHosts in your server.ts. Without it, SSR will silently fall back to CSR.
See: https://angular.dev/guide/security#configuring-allowed-hosts
-
More visible runtime error — the current console.error fallback produces HTTP 200 with an empty <app-root>, which is indistinguishable from a working CSR app. Consider writing to stderr, returning HTTP 500, or including a clear [ACTION REQUIRED] prefix so the message is not lost in log aggregation.
Command
update
Is this a regression?
The previous version in which this bug was not present was
21.1.4
Description
The security patch for GHSA-x288-3778-4hhx introduced a mandatory
allowedHostsconfiguration for
CommonEngine. When it is not configured after upgrading, Angular SSRsilently falls back to client-side rendering — returning a bare
<app-root></app-root>with HTTP 200 and no thrown exception.
Any application upgrading via
ng updateloses SSR silently with:The only signal is a
console.errorto Node.js stdout that is trivially missed,especially in containerized environments where Node stdout is mixed with other logs.
ng updatehas no mention of this requirement, and the migration guide is silent about it.The only documentation is buried in the security guide, far from any upgrade path.
Minimal Reproduction
Generate a standard SSR app on a version before the security patch (last unaffected: 21.1.4):
Confirm SSR works on the unaffected version:
Upgrade to a patched version (first affected: 21.1.5):
Build and start the SSR server again — no changes to server.ts:
Check the SSR response:
Check Node.js stdout — you will see:
Note:
ng updatein step 3 produced no warning or action required message about this.Fix: add
allowedHoststoCommonEngineinserver.ts:Verified results
Angular 21.1.4 — SSR works,
app-rootcontains rendered content:Angular 21.1.5 — SSR silently falls back to CSR after
ng update, no changes toserver.ts:ng updateproduced zero output about this requirement.Exception or Error
Your Environment
Anything else relevant?
CommonEngine@angular/ssr21.2.7 does not include anng-updatekey inpackage.json— there are zero update migrations provided. Runningng update(ornx migrate) completes silently with no output related toallowedHostswhatsoever.What would help:
Migration guide — add a note that
allowedHostsmust be configured inserver.tsafter upgrading, with a link to the security guide. The domains are application-specific so no automation is possible, but a clear callout during upgrade would prevent this.ng updatewarning — print anACTION REQUIREDmessage during the update process, similar to how other breaking changes are surfaced. Example:More visible runtime error — the current
console.errorfallback produces HTTP 200 with an empty<app-root>, which is indistinguishable from a working CSR app. Consider writing to stderr, returning HTTP 500, or including a clear[ACTION REQUIRED]prefix so the message is not lost in log aggregation.