How to Fix: –experimental-https does not work on the network url

6 min read

Next.js --experimental-https network URL fails because the generated certificate does not match your LAN host

The bug shows up the moment you copy the Network URL from a Next.js dev server started with –experimental-https: localhost works, but the IP-based URL on your local network does not. The reason is not the browser, and usually not your app. It is a TLS certificate hostname mismatch problem in development.

Understanding the Root Cause

When you start a Next.js app with next dev --experimental-https, Next.js creates or uses a local development certificate so the browser can connect over HTTPS. That certificate is commonly valid for localhost, and sometimes for a limited set of local names, but the Network URL printed by the dev server is usually based on your machine’s LAN IP such as 192.168.x.x.

In TLS, the browser verifies that the host you typed matches the certificate’s Subject Alternative Name (SAN) entries. If your browser opens https://192.168.1.10:3000 but the certificate only includes localhost, the handshake succeeds only up to the point where identity verification happens, then the browser flags the connection as invalid. That is why:

  • https://localhost:3000 works
  • https://your-network-ip:3000 fails or warns

This behavior is expected from browsers enforcing certificate validation. The issue is that the experimental HTTPS flow does not automatically generate a certificate that covers every LAN IP, hostname, or changing network interface on your machine.

There is also a second layer to the problem: local IPs are not stable. Switching Wi-Fi, VPNs, Docker networks, WSL, or Ethernet can change the active interface. A certificate generated once for one address can immediately become invalid for the next one.

Step-by-Step Solution

The most reliable fix is to run Next.js dev with your own local certificate that explicitly includes the hostname or IP address you want to use on the network.

Option 1: Use a custom local certificate with mkcert

mkcert is the easiest way to create trusted development certificates for localhost, custom local domains, and LAN IPs.

Install mkcert from the official project: mkcert on GitHub.

Then install the local CA:

mkcert -install

Generate a certificate that includes localhost, your machine name, and your LAN IP:

mkcert localhost 127.0.0.1 ::1 192.168.1.10 my-machine.local

This produces files similar to:

localhost+4.pem
localhost+4-key.pem

Now start Next.js using a custom HTTPS server setup that points to those files.

If you are using a custom Node.js server for development:

import { createServer } from 'https'
import { parse } from 'url'
import next from 'next'
import fs from 'fs'

const dev = true
const app = next({ dev })
const handle = app.getRequestHandler()

const httpsOptions = {
  key: fs.readFileSync('./certs/localhost+4-key.pem'),
  cert: fs.readFileSync('./certs/localhost+4.pem'),
}

app.prepare().then(() => {
  createServer(httpsOptions, (req, res) => {
    const parsedUrl = parse(req.url, true)
    handle(req, res, parsedUrl)
  }).listen(3000, '0.0.0.0', () => {
    console.log('HTTPS dev server running on https://localhost:3000')
    console.log('HTTPS network server running on your configured LAN IP')
  })
})

Install dependencies if needed:

npm install next react react-dom

Add a dev script:

{
  "scripts": {
    "dev:https": "node server.js"
  }
}

Then run:

npm run dev:https

Option 2: Use a local DNS hostname instead of a raw IP

If you want fewer certificate changes, use a stable local hostname instead of copying the raw network IP. For example, map a development hostname such as myapp.local to your machine on your LAN or your hosts file, then generate a certificate for that hostname.

mkcert myapp.local localhost 127.0.0.1 ::1

This works well when testing across multiple browsers on the same machine or on devices that can resolve your local hostname.

Option 3: For quick testing only, stay on localhost

If you do not need device testing on phones, tablets, or another machine, use the local URL instead of the network URL:

next dev --experimental-https

Open only:

https://localhost:3000

This avoids the SAN mismatch because the generated certificate was intended primarily for localhost development.

Option 4: Test on another device with a trusted certificate

If you open the site from a phone or another laptop, that device must also trust the certificate authority that signed the cert. If you used mkcert, the certificate is trusted only on the machine where you installed that local CA unless you explicitly trust it on the secondary device too.

That means you may need to:

  • Export and trust your local CA on the test device
  • Use a certificate generated for the exact LAN host being accessed
  • Ensure the device can resolve the hostname or reach the IP
  1. Find your current LAN IP or choose a stable local hostname.
  2. Generate a certificate including that host in the SAN.
  3. Run Next.js with a custom HTTPS server using that certificate.
  4. Open the exact same host that the certificate covers.

Common Edge Cases

1. Your LAN IP changes frequently

If your IP changes after reconnecting to the network, the certificate can become invalid again. Regenerate the cert or move to a stable hostname.

2. Browser still says the certificate is invalid

Check whether the certificate includes the exact host you opened. Browsers validate exact hostname matching for SAN entries. localhost is not the same as 192.168.1.10, and neither is the same as myapp.local.

3. Another device cannot access your dev server at all

This can be unrelated to HTTPS. Verify:

  • The server is listening on 0.0.0.0 instead of only 127.0.0.1
  • Your firewall allows inbound traffic on port 3000
  • VPN or security software is not blocking LAN access

4. The certificate works on your laptop but not on mobile

The mobile device may not trust your local CA. Install and trust it on that device, or use another test approach such as a secure tunnel.

5. HMR or WebSocket warnings appear

When using custom HTTPS setups, ensure that the browser is connecting to the same secure origin and that any WebSocket endpoints also use a valid certificate path. Mixed-origin dev setups can break hot reload behavior.

6. Corporate security tools intercept HTTPS

Some enterprise environments inject their own root certificates or inspect traffic. That can interfere with local development certificates and create confusing trust errors even when your setup is correct.

FAQ

Why does localhost work but the network URL fails?

Because the generated development certificate usually covers localhost, but not your LAN IP. Browsers reject HTTPS when the requested host is not listed in the certificate’s SAN.

Can Next.js automatically generate a valid certificate for my network IP?

Not reliably for every setup. LAN IPs change, machines can have multiple interfaces, and different devices may connect through different names. That is why a custom certificate is the most dependable solution.

Is it safe to bypass the browser warning in development?

Only for short local testing, and it is not ideal. Bypassing warnings hides the real hostname validation issue and can break API calls, service workers, or secure browser features. A properly trusted local certificate is the better fix.

The practical takeaway is simple: –experimental-https is fine for localhost, but the printed Network URL can fail because the certificate identity does not match that address. To make network access work, generate and use a certificate for the exact hostname or IP you plan to open.

Leave a Reply

Your email address will not be published. Required fields are marked *