Fix mongodb error in Next.js API on Netlify
Resolve 'Failed to load external module mongodb-<hash>' mongodb error in Next.js API routes on Netlify. Disable Turbopack, use standalone output, singleton MongoClient, static imports for serverless MongoDB connections. Covers mongodb 403 error too.
How to fix ‘Failed to load external module mongodb-438b504308ffa4be: Error: Cannot find module mongodb-438b504308ffa4be’ runtime error in Next.js API route on Netlify?
Error details:
48790b4b ERROR ⨯ Error: Failed to load external module mongodb-438b504308ffa4be: Error: Cannot find module 'mongodb-438b504308ffa4be'
Require stack:
- /var/task/.next/server/chunks/[root-of-the-server]__c29eba20._.js
- /var/task/.next/server/chunks/[turbopack]_runtime.js
- /var/task/.next/server/app/api/attractions/route.js
- /var/task/node_modules/next/dist/server/require.js
- /var/task/node_modules/next/dist/server/next-server.js
- /var/task/node_modules/next/dist/server/next.js
- /var/task/node_modules/next/dist/server/lib/start-server.js
- /var/task/.netlify/dist/run/next.cjs
This occurs when accessing MongoDB in a Next.js application hosted on Netlify (serverless runtime error).
mongodb.ts code:
import { MongoClient, MongoClientOptions } from "mongodb"
const uri: string = process.env.MONGODB_URI || ''
if ( !uri ) {
throw new Error("Invalid MongoDB URI!")
}
const options: MongoClientOptions = {
// useUnifiedTopology: true,
// useNewUrlParser: true,
}
let client: MongoClient
let clientPromise: Promise<MongoClient>
declare global {
var __mongoClientPromise: Promise<MongoClient> | undefined
}
if (process.env.NEXT_ENV === "development") {
if (!globalThis.__mongoClientPromise) {
client = new MongoClient(uri, options);
globalThis.__mongoClientPromise = client.connect();
}
clientPromise = globalThis.__mongoClientPromise;
} else {
client = new MongoClient(uri, options);
clientPromise = client.connect();
}
export default clientPromise;
What configuration changes or workarounds are needed for MongoDB connections in Next.js serverless deployments on Netlify, especially with Turbopack or dynamic module loading?
This mongodb error — “Failed to load external module mongodb-438b504308ffa4be: Error: Cannot find module ‘mongodb-438b504308ffa4be’” — usually means the MongoDB driver was rewritten as a hashed external by the bundler (Turbopack) and wasn’t actually bundled into Netlify’s serverless function. The reliable fixes are: disable Turbopack for server builds (or force Webpack bundling), build with output: “standalone” so node_modules are included, use static imports and a singleton MongoClient, and make sure your API routes are not compiled for the Edge runtime; if you instead see a mongodb 403 error, verify Atlas credentials and IP/network rules.
Contents
- Symptom: the hashed-module runtime error
- Why the ‘mongodb-
’ mongodb error happens - Quick fixes for mongodb error on Netlify
- Fixing mongodb.ts: singleton + static-import example
- Netlify configuration and environment tips
- Advanced workarounds (force bundling / postbuild copy)
- Testing & verification steps
- Sources
- Conclusion
Symptom: the hashed-module runtime error
You see a runtime crash on Netlify when an API route touches MongoDB and the logs contain a message like:
Error: Failed to load external module mongodb-438b504308ffa4be: Error: Cannot find module 'mongodb-438b504308ffa4be'
Require stack:
- /var/task/.next/server/chunks/[root-of-the-server]__c29eba20._.js
- /var/task/.next/server/chunks/[turbopack]_runtime.js
- /var/task/.next/server/app/api/.../route.js
...
Two important clues are present:
- the module name contains a hash (mongodb-
), and - the stack references .next/server/chunks and a turbopack runtime chunk.
Translated: the bundler rewrote/hashed the mongodb package and the hashed artifact isn’t present or resolvable in the Netlify / AWS Lambda–style runtime, so require() fails at runtime.
If you want the root evidence, see community reports and reproductions where Turbopack produces hashed external names that fail at runtime: https://github.com/vercel/next.js/issues/86866 and https://github.com/vercel/next.js/issues/72077.
Why the ‘mongodb-’ mongodb error happens
Short version: Turbopack (or an incompatible bundling configuration) can mark packages as external and generate hashed module identifiers. Netlify’s runtime then tries to require those hashed externals but the actual driver files aren’t present in the function bundle, so Node throws “Cannot find module”.
A few contributing factors combine here:
- Turbopack rewriting compiled module names into hashed externals (documented in the MongoDB developer guide for Netlify + Next.js) — that guide calls out this exact failure mode and recommends disabling Turbopack for serverless builds: https://www.mongodb.com/developer/languages/javascript/developing-web-application-netlify-serverless-functions-mongodb/
- Next.js/Turbopack issues report identical “Failed to load external module” symptoms when bundled artifacts reference hashed names that aren’t resolvable at runtime: https://github.com/vercel/next.js/issues/86866 and https://github.com/vercel/next.js/issues/72077
- Netlify’s build/runtime choices (Edge vs Node server functions) can also cause trouble when CJS packages (like the mongodb driver) are forced into Edge-compatible bundles — community threads show CJS modules failing in Netlify Edge builds: https://answers.netlify.com/t/next-js-16-project-build-fails-on-netlify/157791
So: bundler + runtime mismatch (Turbopack + Netlify serverless/edge) → module hashed/externalized → runtime can’t resolve the driver.
Quick fixes for mongodb error on Netlify
Apply these in order (each step is fast to try and will often fix the problem):
- Disable Turbopack for production server builds and build standalone bundles
- Edit next.config.js to force the server build to use Webpack and produce a standalone server (this ensures node_modules are packaged into the server output):
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
turbopack: false, // turn Turbopack off for builds that create server functions
},
output: 'standalone', // include node_modules in the server bundle
};
module.exports = nextConfig;
This is the single most effective, widely recommended workaround (see MongoDB’s Netlify guide for the same advice): https://www.mongodb.com/developer/languages/javascript/developing-web-application-netlify-serverless-functions-mongodb/
- Make sure imports are static (no dynamic imports for the driver)
- Use a top-level static import:
import { MongoClient } from 'mongodb'. Dynamic import/require patterns can interact poorly with Turbopack and serverless bundling.
- Ensure the route is using the Node runtime (not Edge)
- Search your API routes for
export const runtime = 'edge'and remove it (or set runtime to Node) if you depend on CJS drivers. Edge runtime doesn’t support many Node-native packages.
- Use the MongoDB singleton pattern (short-lived serverless functions still get warm re-use)
- Keep one connection per process using a global promise variable (example below). That reduces connections and is recommended whether or not the hashed-module issue is present.
- Clear Netlify build cache and redeploy
- Netlify may have cached a bad build artifact. After changing next.config.js, clear the build cache in Netlify and trigger a fresh deploy (the Netlify community threads call this out as a common fix): https://answers.netlify.com/t/next-js-15-build-works-locally-but-fails-on-netlify-due-to-unresolved-module-paths/151470
- Keep Next.js and Netlify’s Next plugin up to date
- The Turbopack/Next.js ecosystem is evolving; a bugfix may arrive in newer releases. If disabling Turbopack isn’t acceptable long-term, track the Next.js issues and update when fixed.
Fixing mongodb.ts: singleton + static-import example
Your file is close — a few improvements make it more robust and conventional:
- Use NODE_ENV for the environment check (Next sets NODE_ENV).
- Use a single global promise variable (avoid creating multiple connect() calls).
- Remove legacy options like useUnifiedTopology (modern drivers no longer need them).
Example (TypeScript):
// lib/mongodb.ts
import { MongoClient } from 'mongodb';
const uri = process.env.MONGODB_URI;
if (!uri) throw new Error('Missing MONGODB_URI environment variable');
declare global {
// eslint-disable-next-line no-var
var __mongoClientPromise: Promise<MongoClient> | undefined;
}
let client: MongoClient;
let clientPromise: Promise<MongoClient>;
if (process.env.NODE_ENV === 'development') {
// In development, use a global so hot reloads don't create new connections
if (!globalThis.__mongoClientPromise) {
client = new MongoClient(uri);
globalThis.__mongoClientPromise = client.connect();
}
clientPromise = globalThis.__mongoClientPromise;
} else {
// In production, create a fresh client (or you can still use a global)
client = new MongoClient(uri);
clientPromise = client.connect();
}
export default clientPromise;
Why this helps:
- Static import and a predictable connection pattern make it easy for the bundler to see the dependency.
- Reusing a promise reduces concurrent connect() calls during warm function reuse.
Note: don’t commit secrets. Set MONGODB_URI via Netlify site settings (see next section).
Netlify configuration and environment tips
A few Netlify-specific items to check:
- Set MONGODB_URI in your site’s Environment variables (Netlify UI). Don’t store credentials in the repo.
- Ensure Node version parity: add engines to package.json, or set Node via Netlify environment so the runtime matches local tests:
- package.json:
"engines": { "node": "18.x" } - Clear Netlify build cache after making config changes (Build & Deploy → Deploys → Clear cache and deploy site).
- If you use Netlify’s Next.js plugin, ensure it’s up to date—older plugin versions can produce unexpected bundle behavior.
- netlify.toml (example, but avoid putting secrets here):
[build]
command = "npm run build"
publish = ".next"
functions = ".netlify/functions"
[build.environment]
NODE_VERSION = "18"
NEXT_TELEMETRY_DISABLED = "1"
Remember: publish/functions settings vary depending on how the Netlify Next plugin is configured. The key is ensuring your build produces serverless artifacts that include the mongodb driver (output: ‘standalone’ or equivalent).
Reference: community threads where build environment parity and clearing cache helped resolve unresolved module errors: https://answers.netlify.com/t/next-js-15-build-works-locally-but-fails-on-netlify-due-to-unresolved-module-paths/151470
Advanced workarounds (force bundling, postbuild copy)
If disabling Turbopack or output: ‘standalone’ is not possible for your workflow, consider these fallbacks — they’re more fragile but sometimes required:
- Force the server Webpack build to include the mongodb package (remove it from externals in next.config.js). Example pattern:
// next.config.js
module.exports = {
webpack: (config, { isServer }) => {
if (isServer && config.externals) {
// remove 'mongodb' from externals so it's bundled into the server build
config.externals = config.externals.filter(ext => {
if (typeof ext === 'string') return !ext.includes('mongodb');
return true;
});
}
return config;
},
};
Test this carefully — Webpack externals shape can vary across Next.js versions.
-
Postbuild copy: write a postbuild script that copies the mongodb package into the final serverless function folder (or into .next/standalone). Ugly, but sometimes quicker than a full rebuild strategy.
-
As a last resort: switch to a lightweight driver/proxy or use a server-side middle layer you fully control (less desirable, more architecture change).
Caveat: these are workarounds. The recommended, simpler path is disabling Turbopack for server builds and producing standalone bundles.
Testing & verification steps
Run these once you apply fixes:
- Local production build
- Run:
npm run build - Start prod server:
npm run start(or if using standalone output:node .next/standalone/server.js) - Hit the same API route and confirm no “Failed to load external module” log.
- Inspect build output
- Look into
.next/serveror.next/standaloneto confirm the mongodb package or its files are present. - Search chunks:
grep -R "mongodb-" .next || true— you should not rely on hashed externals that aren’t present in the deployment bundle.
- Netlify deploy
- Clear cache, deploy, then check Deploy logs and Function logs for the same error.
- If errors persist, download the deployed artifact (Netlify builds are visible in deploy logs) and inspect the .next folder produced by the Netlify build.
- If you run into a mongodb 403 error instead of a module-not-found, verify Atlas:
- User credentials, database/role permissions, and Atlas Network Access (IP allowlist) — a 403-like error is often credentials or network-related, not a bundler issue.
Sources
- MongoDB Developer: Fixing serverless bundling issues and Turbopack guidance — https://www.mongodb.com/developer/languages/javascript/developing-web-application-netlify-serverless-functions-mongodb/
- Next.js GitHub issue where Turbopack produces hashed externals (example) — https://github.com/vercel/next.js/issues/86866
- Next.js GitHub issue showing “Failed to load external module” with Turbopack — https://github.com/vercel/next.js/issues/72077
- Netlify community thread: Next.js build works locally but fails on Netlify — https://answers.netlify.com/t/next-js-15-build-works-locally-but-fails-on-netlify-due-to-unresolved-module-paths/151470
- Netlify community thread: Edge runtime / CJS incompatibility example — https://answers.netlify.com/t/next-js-16-project-build-fails-on-netlify/157791
Conclusion
The hashed-module “Cannot find module ‘mongodb-438b504308ffa4be’” mongodb error is most commonly a bundler/runtime mismatch: Turbopack (or similar) rewrites the mongodb package into a hashed external that Netlify’s serverless runtime can’t resolve. The practical, dependable fixes are to disable Turbopack for server builds, build with output: “standalone” so node_modules are included, keep imports static, use a singleton MongoClient, ensure your API routes run under the Node runtime (not Edge), set MONGODB_URI in Netlify, and clear the Netlify build cache before redeploy. Follow those steps and you’ll eliminate the hashed-module runtime failure; if you still see a mongodb 403 error after that, switch focus to Atlas credentials and network access rules. If you’d like, I can produce a ready-to-apply patch for your repo (next.config.js + improved mongodb.ts + a Netlify checklist).