vercel/next.js · error

An error occurred while loading the instrumentation hook

Error message

An error occurred while loading the instrumentation hook

What it means

Thrown by NextNodeServer.loadInstrumentationModule() in production (non-dev) mode when loading the instrumentation module (instrumentation.ts/js) fails with any error OTHER than MODULE_NOT_FOUND. The instrumentation hook runs custom code at server startup for OpenTelemetry/Sentry/etc., so a runtime error in that user-authored module propagates as this wrapped error with the original as the cause.

Source

Thrown at packages/next/src/server/next-server.ts:366

      }
    }
  }

  protected async handleUpgrade(): Promise<void> {
    // The web server does not support web sockets, it's only used for HMR in
    // development.
  }

  protected async loadInstrumentationModule() {
    if (!this.serverOptions.dev) {
      try {
        this.instrumentation = await getInstrumentationModule(
          this.dir,
          this.nextConfig.distDir
        )
      } catch (err: any) {
        if (err.code !== 'MODULE_NOT_FOUND') {
          throw new Error(
            'An error occurred while loading the instrumentation hook',
            { cause: err }
          )
        }
      }
    }
    return this.instrumentation
  }

  protected async prepareImpl() {
    await super.prepareImpl()
    await this.runInstrumentationHookIfAvailable()
  }

  protected async runInstrumentationHookIfAvailable() {
    await ensureInstrumentationRegistered(this.dir, this.nextConfig.distDir)
  }

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Inspect the `cause` of the thrown Error — it holds the original stack from your instrumentation module; fix the offending line in instrumentation.ts.
  2. Run `next build` again to ensure the instrumentation module is recompiled into distDir, then `next start`.
  3. Temporarily test the instrumentation file in isolation (`node --import ./instrumentation.js` or a unit test) to reproduce the load failure outside Next.
  4. Verify all env vars and external packages required by instrumentation.ts are available in the production environment.

Example fix

// before (instrumentation.ts)
export async function register() {
  Sentry.init({ dsn: process.env.SENTRY_DSN.toUpperCase() }) // throws if SENTRY_DSN undefined
}
// after
export async function register() {
  if (process.env.SENTRY_DSN) {
    Sentry.init({ dsn: process.env.SENTRY_DSN })
  }
}
Defensive patterns

Strategy: try-catch

Try / catch

// In your server bootstrap, guard the Next server start so an instrumentation
// failure surfaces a clear message instead of crashing silently.
try {
  await app.prepare()
} catch (err) {
  if (/loading the instrumentation hook/i.test(err.message)) {
    console.error('instrumentation.ts failed to load:', err.cause)
  }
  throw err
}

Prevention

When it happens

Trigger: Running `next start` (production, not dev) where instrumentation.{ts,js} exists but throws during module evaluation — e.g. a bad import path, a top-level throw, referencing an undefined env var that breaks an imported SDK, or a syntax error. The code calls getInstrumentationModule(dir, distDir) and only swallows err.code === 'MODULE_NOT_FOUND'; every other error is re-thrown wrapped in this message.

Common situations: An observability SDK (Sentry, OpenTelemetry) is initialized in instrumentation.ts with a missing API key env var that causes the SDK init to throw; importing a Node-only module into an edge instrumentation file; a refactor left a broken import; the distDir build of instrumentation is stale after editing the source.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/cd0c2d54a6b848a9. Report an issue: GitHub.