NestJS loosing request with Passport JWT strategy

In order to implement multitenancy in my NestJS app, I create the database connection in a request-scoped provider (depending on request subdomain). Authentication handled by Passport is working fine when using local strategy. However when using JWT strategy later on, the request in my connection provider is undefined:

ERROR [ExceptionsHandler] Cannot read property 'headers' of undefined
TypeError: Cannot read property 'headers' of undefined
    at InstanceWrapper.useFactory [as metatype] (/Users/peterbienek/dev/nestjs/multitenant-typeorm/src/tenancy/tenancy.module.ts:14:29)
    at Injector.instantiateClass (/Users/peterbienek/dev/nestjs/multitenant-typeorm/node_modules/@nestjs/core/injector/injector.js:304:55)
    at callback (/Users/peterbienek/dev/nestjs/multitenant-typeorm/node_modules/@nestjs/core/injector/injector.js:48:41)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)

This is my connection provider:

import { Module, Scope, Global, BadRequestException } from '@nestjs/common';
import { getConnectionManager, createConnection } from 'typeorm';
import * as tenantOrmConfig from './tenant-ormconfig'
import { REQUEST } from '@nestjs/core';

const connectionFactory = {

    provide: 'CONNECTION',
    scope: Scope.REQUEST,
    useFactory: async (req) => {

        let subdomain = req.headers.host.split('.')[0]

        const connectionName = subdomain

        if (subdomain.indexOf('localhost') != -1 || subdomain.indexOf('127.0.0.1') != -1) {
            throw new BadRequestException('Tenant code not valid')
        }

        const connectionManager = getConnectionManager()
        const connectionPublic = connectionManager.get('default')

        if (connectionManager.has(connectionName)) {
            const connection = await connectionManager.get(connectionName)
            return Promise.resolve(connection.isConnected ? connection : connection.connect())
        }else{

            console.log("CREATING CONNECTION ", connectionName)
            
            connectionPublic.query(`CREATE SCHEMA IF NOT EXISTS ${connectionName}`)

            await createConnection({
                ...tenantOrmConfig,
                name: connectionName,
                type: 'mysql',
                database: connectionName,
            })

            const connection = await connectionManager.get(connectionName)
            return Promise.resolve(connection.isConnected ? connection : connection.connect())
        }


    },
    inject: [REQUEST]
    
}

@Global()
@Module({
    providers: [connectionFactory],
    exports: ['CONNECTION']
})
export class TenancyModule { }

JWT strategy looks like this:

import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from '../auth.service';
import { PassportStrategy } from '@nestjs/passport';
import { ModuleRef, ContextIdFactory } from '@nestjs/core';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { SETTINGS } from 'src/app.config';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {

    constructor(
        private moduleRef: ModuleRef) {
        super({
            passReqToCallback: true,
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            ignoreExpiration: false,
            secretOrKey: SETTINGS.JWT_SECRET,
        });
    }

    async validate(
        payload: any, request: Request
        ): Promise<any> {

        const contextId = ContextIdFactory.getByRequest(request);
        const authService = await this.moduleRef.resolve(AuthService, contextId);

        const user = await authService.validateUserByJwt(payload);
        if (!user) {
            throw new UnauthorizedException();
        }
        return user;
    }

}

Local strategy (almost identical):

import { ModuleRef, ContextIdFactory } from '@nestjs/core';
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from '../auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy, 'local') {
  
  constructor(private moduleRef: ModuleRef) {
    super({passReqToCallback: true, usernameField: 'email'});
  }

  async validate(
    request: Request,
    email: string, 
    password: string
    ): Promise<any> {

    const contextId = ContextIdFactory.getByRequest(request);
    const authService = await this.moduleRef.resolve(AuthService, contextId);
    const user = await authService.validateUser(email, password);

    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }

}

Auth service using the connection:

import { Scope, Injectable, Inject, NotFoundException, UnauthorizedException, BadRequestException } from "@nestjs/common";
import { JwtService } from "@nestjs/jwt";
import { JwtPayloadService } from "./jwt.payload.service";
import { JwtPayload } from "./interfaces/jwt-payload.interface";
import { User } from "src/common/users/entities/user.entity";
import { UsersService } from "src/common/users/users.service";
import { Repository } from "typeorm";
import * as bcrypt from "bcrypt";

export class AuthService {
  userRepository: Repository<User>;

  constructor(
    @Inject("CONNECTION") connection,
    private jwtService: JwtService,
    private jwtPayloadService: JwtPayloadService,
    private usersService: UsersService
  ) {
    this.userRepository = connection.getRepository(User);
  }

  async validateUser(email: string, pass: string): Promise<any> {
    const user = await this.usersService.validate(email);

    const isPasswordMatching = await bcrypt.compare(pass, user.password);

    if (user && isPasswordMatching) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }

  async validateUserByJwt(payload: JwtPayload) {
    console.log("payload", payload);

    const user = await this.usersService.findOneByEmail(payload.email);

    if (user) {
      return this.jwtPayloadService.createJwtPayload(user);
    } else {
      throw new UnauthorizedException();
    }
  }

}

How can the local strategy work and the JWT strategy not?