nestjs/nest · error · InternalServerErrorException
HTTP adapter does not support filtering on host: "${host}"
Error message
HTTP adapter does not support filtering on host: "${host}" What it means
Host-restricted routes (`@Controller({ path: 'x', host: 'api.example.com' })`) are implemented as a wrapper that matches `req.hostname` against the configured host patterns and falls through to `next()` when nothing matches. When the underlying HTTP adapter registers the handler directly (not as middleware with a next function — the Fastify case) there is no fallback, so a request whose hostname matches none of the patterns ends in InternalServerErrorException 'HTTP adapter does not support filtering on host'.
Source
Thrown at packages/core/router/router-explorer.ts:388
) => {
(req as Record<string, any>).hosts = {};
const hostname = httpAdapterRef.getRequestHostname(req) || '';
for (const exp of hostRegExps) {
const match = hostname.match(exp.regexp);
if (match) {
if (exp.keys.length > 0) {
exp.keys.forEach((key, i) => (req.hosts[key.name] = match[i + 1]));
} else if (exp.regexp && match.groups) {
for (const groupName in match.groups) {
req.hosts[groupName] = match.groups[groupName];
}
}
return handler(req, res, next);
}
}
if (!next) {
throw new InternalServerErrorException(
unsupportedFilteringErrorMessage,
);
}
return next();
};
}
private applyVersionFilter<T extends HttpServer>(
router: T,
routePathMetadata: RoutePathMetadata,
handler: Function,
) {
const version = this.routePathFactory.getVersion(routePathMetadata)!;
return router.applyVersionFilter(
handler,
version,
routePathMetadata.versioningOptions!,
);View on GitHub (pinned to dd75d7bd8c)
Solutions
- Add the hostnames you actually serve to the filter: `@Controller({ host: ['api.example.com', 'localhost'] })` or a parametrized pattern like `:subdomain.example.com`.
- Switch to the Express adapter if full host-based (virtual host) routing is a hard requirement — it supports the middleware fallback.
- Fix the Host header at the proxy/ingress level (preserve upstream Host) so the app sees the expected hostname.
- As a safety net, map the resulting InternalServerError to a 404 with an exception filter for unmatched host traffic.
Example fix
// before (Fastify + only prod host in filter -> curl http://localhost:3000/x => 500)
@Controller({ path: 'reports', host: 'api.example.com' })
export class ReportsController {}
// after
@Controller({ path: 'reports', host: ['api.example.com', 'localhost'] })
export class ReportsController {} Defensive patterns
Strategy: validation
Validate before calling
// Validate Host before host-filtered routes run; respond 404 instead of a 500
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
const ALLOWED_HOSTS = ['api.example.com', 'localhost'];
@Injectable()
export class HostAllowlistMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const hostname = (req.hostname || '').toLowerCase();
if (!ALLOWED_HOSTS.includes(hostname)) {
return res.status(404).json({ statusCode: 404, message: 'Unknown host' });
}
next();
}
}
// register with consumer.apply(HostAllowlistMiddleware).forRoutes('*') BEFORE host-filtered controllers Prevention
- Include every hostname the service is reached by (localhost, container IP, internal ingress) in host filters.
- Prefer the Express adapter when host-based routing is central to the app.
- Preserve the Host header in proxies/ingresses so filters match what you configured.
- Cover host-filtered routes in smoke tests using the exact Host header production uses.
When it happens
Trigger: Using Fastify with host-based controllers and accessing the app through a hostname/IP not covered by any pattern (localhost, 127.0.0.1, container IP, another domain); a host regex that does not account for the port-bearing Host header value; moving an Express app with virtual hosts to Fastify where the middleware-style registration is unavailable; API gateways rewriting Host before the request reaches the service.
Common situations: Local development against localhost for a controller restricted to 'api.example.com'; Kubernetes ingress sending internal hostnames; multi-tenant SaaS routing by subdomain behind proxies; smoke tests hitting the pod IP directly.
Related errors
- Conflicting HTTP routes detected: - ${messages} Adjust rou
- An invalid controller has been detected. "${className}" does
- You must return an Observable stream to use Server-Sent Even
- Cannot ${method} ${url}
- Content-Type doesn't match Reply body, you might need a cust
AI-assisted analysis of nestjs/nest@dd75d7bd8c (2026-08-21).
Data as JSON: /api/errors/ad31b34b6ec38414.
Report an issue: GitHub.