Hi all,
I'm looking for insights from anyone who knows the deep secrets of `RedirectResponseSubscriber` / `UrlHelper::externalIsLocal()` / the Symfony request context, or – even better – anyone who hit the same wall and solved it.
**Environment**
- Local test bench: MAMP PRO, Apache 2.4.66 (mod_fastcgi), vhost `d11access` on custom port `:8890`, SSL enabled (all requests over `https://d11access:8890`).
- Final target: a shared host with fixed docroot `public_html`, Drupal in a `web/` subdirectory (composer `drupal/recommended-project` layout), hence the .htaccess aliasing below.
- **Drupal 10.6.15 + PHP 8.3: this exact setup works flawlessly** (install, navigation, login, logout).
- **Drupal 11.4.5 + PHP 8.3 / 8.4 / 8.5 (same result on all): install and anonymous navigation work, but every form-driven redirect – starting with login – dies.**
**The setup (identical on 10.6 and 11.4)**
Root `.htaccess` (outside `web/`):
```apache
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?d11access:8890$
RewriteCond %{REQUEST_URI} !^/web/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /web/$1
RewriteCond %{HTTP_HOST} ^(www.)?d11access:8890$
RewriteRule ^(/)?$ web/index.php [L]
```Top of `settings.php`:
```php
<?php
if (isset($GLOBALS['request']) and
'/web/index.php' === $GLOBALS['request']->server->get('SCRIPT_NAME')) {
$GLOBALS['request']->server->set('SCRIPT_NAME', '/index.php');
}
// Trusted host patterns.
$settings['trusted_host_patterns'] = [
'^d11access$',
];
$base_url = 'https://d11access';
// phpcs:ignoreFile
```**What works on 11.4.5**: installation, anonymous navigation, clean URLs (no `/web` anywhere; e.g. the login form renders as `<form action="/user/login">`, so Symfony's `Request::getBaseUrl()` resolves to `''`).
**What fails on 11.4.5**: POSTing `/user/login` with valid credentials always throws:
```
Redirects to external URLs are not allowed by default, use \Drupal\Core\Routing\TrustedRedirectResponse for it.
```
Same for logout and any form submit that ends in a redirect.
**Already tried / ruled out (all on 11.4.5)**
1. Every `$base_url` × `trusted_host_patterns` combination:
- `trusted ^d11access:8890$` + `$base_url https://d11access:8890` → "The provided host name is not valid for this server."
- `trusted ^d11access$` + `$base_url https://d11access:8890` → the external-redirect error on login.
- `trusted ^d11access:8890$` + `$base_url https://d11access` → host not valid.
- `trusted ^d11access$` with `$base_url` removed entirely → still the external-redirect error.
2. Forcing `$_SERVER['HTTPS'] / SERVER_PORT / SCRIPT_NAME` in settings.php. Side discovery: on D11 `$GLOBALS['request']` is **not** set yet when `settings.php` is loaded, so the classic D8–D10 `SCRIPT_NAME` hack above is dead code on 11.x (it never runs).
3. Full cache nuking: all `cache_*` tables truncated, `sites/default/files/php|css|js` emptied, `drush cr`, fresh incognito sessions.
4. Live request dump at bootstrap: `HTTPS=on`, `SERVER_PORT=8890`, `HTTP_HOST=d11access:8890`, `SCRIPT_NAME=/index.php` – the request looks perfectly local, yet the generated redirect is treated as external.
The same MAMP vhost, same .htaccess, same settings.php: works on 10.6.15, fails on 11.4.5 on PHP 8.3/8.4/8.5 alike – so this doesn't look like a PHP issue, it looks like a core behavior change.
**Questions**
- What changed between 10.6 and 11.x in `RedirectResponseSubscriber`, `UrlHelper::externalIsLocal()` or the request/context handling that breaks the long-used "alias a subdirectory docroot via .htaccess" pattern?
- Is there a supported way on D11 to run the recommended-project layout on shared hosting (fixed docroot, Drupal in `web/`, served from the root) without hitting this?
- Related issues I'm aware of: #3569379, #2574891, #2612160.
Happy to provide full stack traces or further request dumps. Thanks in advance!
Comments
_-_
That sounds a lot like #2612160: .htaccess redirect on shared hosting error: Redirects to external URLs are not allowed by default.
Yes, very similar, but that
Yes, very similar, but that one is about Drupal 8 :)
All those workarounds that seem to have solved the issue in that case are already in place in my configuration.
And as I mentioned, with D 10.6.15/PHP 8.3.x/8.4.x and up to D 11.3.1/PHP 8.3.x/8.4.x, that code works perfectly fine.
It’s with the new 11.4.5 that it stops working :)
But that exact scenario is
But that exact scenario is actually described in the Issue summary: #2612160: .htaccess redirect on shared hosting error: Redirects to external URLs are not allowed by default was created for Drupal 8, and a workaround for settings.php was shared November 2016, which seems to be the one you are using.
It worked until Drupal 11.3.x, but broke in Drupal 11.4.0 (see Issue Summary), and more recent workarounds are shared in the comments after August 2026. There is also #3569379: Mitigate SCRIPT_NAME issues when using limited hosting or complex domains.
UPDATE: The adjusted .htaccess could also play a role?