Repository navigation
[@angular/ssr] RESPONSE_INIT headers are ignored during redirects returned by UrlTree guards #33473
Description
Command
serve, build
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
No response
Description
In our application, we need to issue 301 Moved Permanently redirects using a UrlTree inside a canActivate guard. However, we also need to attach custom Cache-Control headers to prevent the highly aggressive, permanent caching that browsers typically apply to 301s.
By default, returning a UrlTree triggers a 302 redirect. We successfully modified the status code to 301 by injecting RESPONSE_INIT and mutating the status:
responseInit.status = 301; // This works perfectly
However, when we attempt to add custom headers to the redirect response using the same RESPONSE_INIT object, they are completely ignored in the final response:
responseInit.headers = { 'X-Test-Header': 'Qwe12345' }; // This is ignored
I dug into the angular-cli source code and found the likely culprit in @angular/ssr.
In packages/angular/ssr/src/app.ts, when handling redirects, the status is correctly extracted from responseInit, but the headers are passed from the matchedRoute instead of picking up or merging the headers defined in responseInit.
Line 356 in app.ts (commit 010cef6):
return createRedirectResponse(result.redirectTo, responseInit.status, headers);
(Notice responseInit.headers is not used here).
In my opinion, if modifying responseInit.headers during a guard execution that returns a UrlTree, those headers should be merged into or applied to the resulting redirect response, just as responseInit.status is.
I am opening this to ask if this is an undocumented, intended behavior or a bug? If it is intended, are there plans to support modifying/adding redirect headers in the future? If it's a bug, I'd love to see it fixed so we can properly manage our cache headers on 301s. Thanks!
(I will provide minimal reproduction repository if necessary, but it's very easy to reproduce on a new empty project using the steps below)
Minimal Reproduction
- Set up an Angular SSR app with a child route.
- Add a
canActivateguard to the route that returns aUrlTreepointing back to home. - In the guard, inject
RESPONSE_INIT. - Mutate it:
responseInit.status = 301andresponseInit.headers = { 'X-Test-Header': 'Qwe12345' }. - Run the SSR server and request the child route.
- Observe the network tab: The response is a
301, butX-Test-Headeris missing.
Exception or Error
Your Environment
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI : 22.0.4
Angular : 22.0.2
Node.js : 24.18.0
Package Manager : npm 11.16.0
Operating System : darwin arm64
┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build │ 22.0.4 │ ^22.0.4 │
│ @angular/cli │ 22.0.4 │ ^22.0.4 │
│ @angular/common │ 22.0.2 │ ^22.0.0 │
│ @angular/compiler │ 22.0.2 │ ^22.0.0 │
│ @angular/compiler-cli │ 22.0.2 │ ^22.0.0 │
│ @angular/core │ 22.0.2 │ ^22.0.0 │
│ @angular/forms │ 22.0.2 │ ^22.0.0 │
│ @angular/platform-browser │ 22.0.2 │ ^22.0.0 │
│ @angular/platform-server │ 22.0.2 │ ^22.0.0 │
│ @angular/router │ 22.0.2 │ ^22.0.0 │
│ @angular/ssr │ 22.0.4 │ ^22.0.4 │
│ rxjs │ 7.8.2 │ ~7.8.0 │
│ typescript │ 6.0.3 │ ~6.0.2 │
│ vitest │ 4.1.9 │ ^4.0.8 │
└───────────────────────────┴───────────────────┴───────────────────┘
Anything else relevant?
No response
Activity
fix(@angular/ssr): preserve response headers during redirect
fix(@angular/ssr): preserve response headers during redirect
fix(@angular/ssr): preserve response headers during redirect
fix(@angular/ssr): preserve response headers during redirect
fix(@angular/ssr): preserve response headers during redirect
fix(@angular/ssr): preserve response headers during redirect
fix(@angular/ssr): preserve response headers during redirect
angular-automatic-lock-bot commentedon Jul 30, 2026
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.