
You've tested your Next.js application locally—everything builds perfectly. You push to your CI/CD pipeline, kick off a Docker build, and suddenly you're staring at this cryptic error:
invalid unicode code point at line 1 column 43757
The build crashes. No stack trace pointing to your code. Just Terser complaining about Unicode during minification. If you're reading this, you've likely already wasted hours trying to figure out which file is causing the problem.
Here's the frustrating part: this error almost exclusively occurs in Dockerized environments, particularly when using Alpine-based Node.js images. Your local machine builds the same code without issues. This isn't a bug in your code—it's an environmental incompatibility between your Docker base image and Next.js's minification process.
This article breaks down exactly why the Next.js Terser Invalid Unicode Code Point error happens, why it's Docker-specific, and how to fix it without compromising your production build quality.
When running npm run build or next build inside a Docker container, the build process fails during the minification phase. The error looks something like this:
> next build
▲ Next.js 14.2.5
Creating an optimized production build ...
✓ Compiled successfully
✓ Linting and checking validity of types
✓ Collecting page data
Generating static pages (0/8)
Error: invalid unicode code point at line 1 column 43757
at Terser.minify (/app/node_modules/terser/lib/minify.js:104:15)This error is particularly insidious because:
The issue was reported on GitHub (#69263) where developers consistently noted the problem appears when deploying to cloud VMs using Docker, particularly with Debian or Alpine-based containers.
Terser, the JavaScript minifier, processes your bundled code and encounters a byte sequence it interprets as an invalid Unicode code point. This typically happens when:
The column number (43757 in the example) points to a position in a minified bundle, not your source code. Tracking down the exact problematic character is nearly impossible without significant debugging effort.
The root cause comes down to a fundamental difference in how different Linux distributions handle low-level C library operations, particularly around Unicode and character encoding.
Many developers choose Alpine-based Docker images (node:alpine, node:20-alpine) for their small footprint. Alpine images can be 5-10x smaller than their Debian equivalents. However, Alpine uses musl libc instead of the standard glibc that most Linux distributions use.
This difference matters because:
Here's what a typical problematic Dockerfile looks like:
# ❌ BROKEN: Alpine base image causes Unicode minification issues
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
# This build step fails with "invalid unicode code point"
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]You might notice that Next.js uses SWC (a Rust-based compiler) for minification by default, not Terser. So why does the error mention Terser?
The answer is that SWC doesn't handle all minification scenarios. Certain code patterns, particularly from third-party packages, may still be processed by Terser as a fallback. Additionally, some Next.js configurations or plugins (like next-pwa) can introduce Terser into the build pipeline.
Even with swcMinify: true explicitly set in your config, the error can still occur because:
Why does this only happen in Docker? Your local development environment likely runs on macOS or Windows (or a standard Linux distribution with glibc). These environments have complete locale support and use the same C library conventions that Node.js and its native dependencies were primarily developed against.
When you build inside an Alpine container:
LANG and LC_ALL environment variables may be unsetThere are several approaches to fixing the Next.js Terser Invalid Unicode Code Point error, ranging from quick workarounds to proper long-term solutions.
The most reliable fix is to use a Debian-based Node.js image instead of Alpine:
# ✅ FIXED: Debian-based image with proper Unicode support
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]The node:20-slim image is a minimal Debian-based image that's larger than Alpine but still reasonably sized (approximately 200MB vs 50MB for Alpine). It uses glibc and has proper locale support out of the box.
Trade-offs:
If you absolutely must use Alpine for image size reasons, you can try installing locale support:
# ⚠️ PARTIAL FIX: Alpine with locale support
FROM node:20-alpine
# Install locale support
RUN apk add --no-cache icu-libs icu-data-full
# Set locale environment variables
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]Note: This approach doesn't always work because the underlying musl libc behavior remains unchanged. The locale settings help some scenarios but don't address the fundamental glibc/musl incompatibility.
As a temporary workaround for debugging or development environments, you can disable minification entirely:
// next.config.js
// ❌ NOT RECOMMENDED FOR PRODUCTION: Disables all minification
/** @type {import('next').NextConfig} */
const nextConfig = {
swcMinify: false,
webpack: (config, { isServer }) => {
if (!isServer) {
config.optimization.minimize = false;
}
return config;
},
};
module.exports = nextConfig;Warning: This produces significantly larger bundles and should never be used in production. It's only useful for confirming that minification is indeed the source of the problem.
For the best of both worlds—small runtime image but reliable builds—use a multi-stage Dockerfile:
# ✅ BEST PRACTICE: Multi-stage build
# Stage 1: Build using Debian-based image
FROM node:20-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Production runtime (can even use Alpine here since we're not building)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# Copy only necessary files from builder
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
CMD ["node", "server.js"]This approach:
Note: This requires output: 'standalone' in your next.config.js:
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: "standalone",
};
module.exports = nextConfig;Encountering the Next.js Terser Invalid Unicode Code Point error is a symptom of a broader issue: environment inconsistency between development and production. Here's how to prevent this class of problems:
Choose one of these strategies and apply it consistently across all projects:
Strategy A: Always Use Debian-Based Images
# Preferred base images for Next.js applications
FROM node:20-slim # Minimal Debian, ~200MB
FROM node:20-bookworm # Full Debian, ~900MB
FROM node:20 # Default Debian, ~900MBStrategy B: Multi-Stage with Alpine Runtime If image size is critical, use the multi-stage approach shown above. Build with Debian, run with Alpine.
Regardless of which base image you use, always set locale environment variables:
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8This ensures consistent character encoding behavior across all environments.
Use specific version tags, not latest or major version tags:
# ❌ Avoid: Can change unexpectedly
FROM node:latest
FROM node:20
# ✅ Prefer: Pinned version for reproducibility
FROM node:20.10.0-slimAdd a build verification step to your CI pipeline that mirrors your production Docker build:
# .github/workflows/build-test.yml
name: Build Test
on: [push, pull_request]
jobs:
docker-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:test .
- name: Verify container starts
run: |
docker run -d --name test-container -p 3000:3000 myapp:test
sleep 10
curl -f http://localhost:3000 || exit 1Add a section to your project's README specifying the tested Docker base images:
## Docker Requirements
This project requires a glibc-based Node.js image for building.
**Tested Base Images:**
- `node:20-slim` ✅
- `node:20-bookworm` ✅
- `node:20-alpine` ❌ (Unicode minification errors)node:alpine to node:slim or another Debian-based image—this resolves the issue without code changesLANG=C.UTF-8 and LC_ALL=C.UTF-8 in your Dockerfiles regardless of base image choiceContent creator and developer at UICraft Marketplace, sharing insights and tutorials on modern web development.
Save hours of development time with our premium Next.js templates. Built with Next.js 16, React 19, and Tailwind CSS 4.
Get the latest articles, tutorials, and product updates delivered to your inbox.

Getting "JavaScript heap out of memory" during Next.js builds? This guide explains why large service account files cause memory exhaustion and shows you how to fix it using proper secret management and .gitignore patterns.

When you deploy a new version of your Next.js application, existing clients can silently fail when calling Server Actions. This happens because Next.js generates new encryption keys per build, making old client sessions incompatible. Here's the advanced fix using persistent encryption keys.

The "Props must be serializable" warning in Next.js confuses many developers who mark every client component with 'use client'. This guide explains the root cause and shows you exactly how to fix it by understanding the true purpose of client-server boundaries.