vitest-dev/vitest · error · Error
import of ' ' by undefined is not supported: http can only…
Error message
import of '${fileUrl}' by undefined is not supported: http can only be used to load local resources (use https instead). What it means
In the vm pool, createNetworkModule() refuses to fetch modules over plain http unless the host is local. It allows only hostname 'localhost', '::1', or any address in the 127.0.0.0/8 loopback block (#httpIp = IPnumber('127.0.0.0') masked with /8). Any other http host is rejected and the importer is reported as 'undefined' because the executor has no importer context.
Solutions
- Serve the resource over https instead (http is rejected for non-local hosts by design).
- Make the host loopback: use http://localhost/... or http://127.x.x.x/... so it passes the 127.0.0.0/8 check.
- Use a pool other than vm (threads/forks) if you genuinely need http imports from a non-local host, since this gate is vm-pool specific.
- Vendor the module locally and import it via a file:// URL.
Example fix
// before
await import('http://10.0.0.5/api/mock.js')
// after
await import('http://localhost/api/mock.js')
// or
await import('https://10.0.0.5/api/mock.js') Defensive patterns
Strategy: validation
Validate before calling
import { isLoopback } from 'node:net'
function allowedHttp(url) {
if (!url.startsWith('http://')) return true
const h = new URL(url).hostname
return h === 'localhost' || h === '::1' || /^127\./.test(h)
}
if (!allowedHttp(specifier)) throw new Error('use https or localhost') Type guard
function isLocalHttp(u) {
if (!u.protocol.startsWith('http:')) return true
return ['localhost','::1'].includes(u.hostname) || /^127\./.test(u.hostname)
} Prevention
- Prefer https:// for any remote module import in tests.
- Bind dev servers used by tests to localhost/127.0.0.1.
- Use a non-vm pool if you must import over http from a non-loopback host.
When it happens
Trigger: A test or module does a dynamic import of an http:// URL whose hostname is a literal IPv4 outside 127.0.0.0/8 (e.g. http://10.0.0.1/mod.js or http://192.168.1.5/x.js) while running in the vm pool. Localhost and 127.x.x.x are allowed; everything else is blocked.
Common situations: Pointing a test at a dev server on a LAN IP, a Docker bridge address, or a service mesh sidecar over http. Also happens when an http URL is hardcoded in a config or fixture and the dev machine resolves to a non-loopback address.
Related errors
- Expected IP address, received
- Access denied to " ". See Vite config documentation for…
- Access denied to " ". See Vite config documentation for…
- Benchmark artifact path
- Cannot import " ": its vm context was torn down.
AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11).
Data as JSON: /api/errors/0b44918370147972.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vitest/src/runtime/vm/esm-executor.ts:381
const cached = this.moduleCache.get(fileUrl)
if (cached) {
return cached
}
const m = this.loadWebAssemblyModule(getCode(), fileUrl)
this.moduleCache.set(fileUrl, m)
return m
}
public async createNetworkModule(fileUrl: string): Promise<VMModule> {
// https://nodejs.org/api/esm.html#https-and-http-imports
if (fileUrl.startsWith('http:')) {
const url = new URL(fileUrl)
if (
url.hostname !== 'localhost'
&& url.hostname !== '::1'
&& (IPnumber(url.hostname) & IPmask(8)) !== this.#httpIp
) {
throw new Error(
// we don't know the importer, so it's undefined (the same happens in --pool=threads)
`import of '${fileUrl}' by undefined is not supported: `
+ 'http can only be used to load local resources (use https instead).',
)
}
}
return this.createEsModule(fileUrl, () =>
fetch(fileUrl).then(r => r.text()))
}
public async loadWebAssemblyModule(source: Buffer<ArrayBuffer>, identifier: string): Promise<VMModule> {
const cached = this.moduleCache.get(identifier)
if (cached) {
return cached
}
const wasmModule = await WebAssembly.compile(source)View on GitHub (pinned to 1fa9837ec2)