Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERR_SSL_VERSION_OR_CIPHER_MISMATCH when both --https and server.https provided #10058

Closed
7 tasks done
JakeYallop opened this issue Sep 9, 2022 · 8 comments · Fixed by #14681
Closed
7 tasks done

ERR_SSL_VERSION_OR_CIPHER_MISMATCH when both --https and server.https provided #10058

JakeYallop opened this issue Sep 9, 2022 · 8 comments · Fixed by #14681
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)
Milestone

Comments

@JakeYallop
Copy link

JakeYallop commented Sep 9, 2022

Describe the bug

When using server.https set to true, subsequently passing the --https CLI flag to vite causes a ERR_SSL_VERSION_OR_CIPHER_MISMATCH when trying to load the page served by the dev server. Reloading the page does not have any effect on the issue.

The reproduction steps are listed below, additionally, the reproduction stackblitz link with the project set up as stated below also errors out in an odd way.

  • npm create vite
  • react
  • typescript
  • Add
  {
      server: { https: true }
  }

to vite.config.ts

In package.json, under scripts, dev, pass --https to vite.

The above reproduces with both https: true, and a custom SSL cert and key file https: { key: ..., cert: ...} . I ran into this issue when I was resurrecting an older project that I hadn't visited for a few months - I had a specific cert and key file, but was also passing --https in my startup script. This suggests that this is a regression, and that this scenario was working at some point with vite 3.x.

Reproduction

https://stackblitz.com/edit/vitejs-vite-8esgks?file=package.json,vite.config.ts&terminal=dev

System Info

System:
    OS: Windows 10 10.0.19043
    CPU: (12) x64 AMD Ryzen 5 3600 6-Core Processor
    Memory: 1.94 GB / 15.95 GB
  Binaries:
    Node: 16.13.2 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 7.19.1 - ~\AppData\Roaming\npm\npm.CMD
  Browsers:
    Edge: Spartan (44.19041.1266.0), Chromium (105.0.1343.27)

Used Package Manager

yarn

Logs

No response

Validations

@bluwy
Copy link
Member

bluwy commented Sep 13, 2022

@bluwy bluwy closed this as completed Sep 13, 2022
@JakeYallop
Copy link
Author

JakeYallop commented Sep 13, 2022

Yep - that is not the issue. I realise the repro I provided does not clearly get this across, but the above repros even using a valid custom certificate.

Interestingly, when passing the cert file via a plugin, it does not reproduce. I'm not sure how best to show a repro for this, as it uses a certificate that would need to be added to the certificate store on the dev machine.

@bluwy,
Are you able to re-open this?

@bluwy
Copy link
Member

bluwy commented Sep 13, 2022

It would be great if you can provide repro steps for the custom local certificate you mention, otherwise there isn't a way for us to debug and fix this.

@JakeYallop
Copy link
Author

@bluwy, I've included additional repro steps, and the weird plugin behaviour I saw whilst debugging that I didn't document originally as I didn't want to dilute the focus away from the main issue.

I've also included the exact steps I used to generate my certificate (I'm a .NET dev primarily), in case it matters.

The exact steps I followed to generate my certificate was the following:

dotnet dev-certs https --export-path "./cert.pem" --format Pem --no-password

This is then passed into the config file:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

//implementation copied from the ssl cert plugin
function certPlugin(keyPath, certPath): Plugin {
  return {
    name: "vite:cert-plugin",
    async config(config) {
      const https = () => ({
        https: {
          key: keyPath,
          cert: certPath,
        },
      });
      return {
        server: https(),
      };
    },
  };
}

const certPath = "./cert.pem";
const keyPath = "./cert.key";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    //certPlugin(keyPath, certPath)
  ],
  server: {
    https: {
      key: keyPath,
      cert: certPath,
    },
  },
});

Passing in the cert and key via server.https directly in the config results in the following.

image,

After commenting in the certPlugin:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

//implementation copied from the ssl cert plugin
function certPlugin(keyPath, certPath): Plugin {
  return {
    name: "vite:cert-plugin",
    async config(config) {
      const https = () => ({
        https: {
          key: keyPath,
          cert: certPath,
        },
      });
      return {
        server: https(),
      };
    },
  };
}

const certPath = "./cert.pem";
const keyPath = "./cert.key";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
-   //certPlugin(keyPath, certPath)
+    certPlugin(keyPath, certPath)
  ],
  server: {
    https: {
      key: keyPath,
      cert: certPath,
    },
  },
});

the app runs successfully and loads to the default screen.

Show

image

package.json (note the --https passed to vite):

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite --https --open",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.17",
    "@types/react-dom": "^18.0.6",
    "@vitejs/plugin-react": "^2.1.0",
    "typescript": "^4.6.4",
    "vite": "^3.1.0"
  }
}

if we remove --https from the package.json, and comment out the cert plugin once again (to go back to the failure case previously):

package.json (removed the --https):

{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
-    "dev": "vite --open --https",
+    "dev": "vite --open",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.17",
    "@types/react-dom": "^18.0.6",
    "@vitejs/plugin-react": "^2.1.0",
    "typescript": "^4.6.4",
    "vite": "^3.1.0"
  }
}
Show code...
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

//implementation copied from the ssl cert plugin
function certPlugin(keyPath, certPath): Plugin {
  return {
    name: "vite:cert-plugin",
    async config(config) {
      const https = () => ({
        https: {
          key: keyPath,
          cert: certPath,
        },
      });
      return {
        server: https(),
      };
    },
  };
}

const certPath = "./cert.pem";
const keyPath = "./cert.key";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    //certPlugin(keyPath, certPath)
  ],
  server: {
    https: {
      key: keyPath,
      cert: certPath,
    },
  },
});

The app then runs successfully once again.

@bluwy bluwy reopened this Sep 14, 2022
@jchanes04
Copy link

I was also able to reproduce on a SvelteKit 1.0 project on Vite 4.0.4. Same story as above, passing in key information to the https option did not work without also implementing this plugin.

On a related issue, there also seems to be ambiguity in the docs about whether the key/cert parameters accept the keys as strings or the file paths. The Vite docs defer this to the Node docs, but those yet again refer to another link to a different function's documentation, which still does not rectify this question. It appears that for me, either using the string representation or the file path of the key/cert worked, but this may be a point of confusion for others.

@kevinrjones
Copy link

Just to confirm that this is also the same for me (on Vite 3.2.5) - if I don't include the 'certPlugin' I get the "ERR_SSL_VERSION_OR_CIPHER_MISMATCH" error, with the plugin it all works OK.

I'm on MacOSX and used openssl to generate the certificates (which work fine in other environments such as Parcel)

@Strandedpirate
Copy link

This will get you TLS certificate setup without any hacks. My certs were created and signed by a root CA that I made/control, and is already in the windows certificate store. I had no issue with Chrome with this setup. Also note the use of fs.readFileSync for the key/cert.

vite.config.ts

import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react-swc'
import fs from 'fs'

const certPath = '../scripts/docker/configuration/certificates/localhost.crt'
const keyPath = '../scripts/docker/configuration/certificates/localhost.key'

// https://vitejs.dev/config/
export default defineConfig(({ command, mode, ssrBuild }) => {
  const env = loadEnv(mode, process.cwd(), '');
  const port = parseInt(env.VITE_PORT);

  return {
    server: {
      // origin: 'https://local.aperture.buildasign.io:36306',
      host: 'local.aperture.buildasign.io',
      strictPort: true,
      port,
      https: {
        key: fs.readFileSync(keyPath),
        cert: fs.readFileSync(certPath),
      },
    },
    plugins: [react()],
  };
});

@sapphi-red sapphi-red added this to the 5.0 milestone Mar 25, 2023
@sapphi-red sapphi-red added the p2-edge-case Bug, but has workaround or limited in scope (priority) label Aug 25, 2023
@mikemoone
Copy link

Just chiming in because I landed here after initially running into the same issue. The config given by @Strandedpirate will definitely work, but my sequence as somebody adding Vite to a project for the first time was:

  1. Initially tried getting https working by just appending --https to the dev script "dev": "npx vite --https"
  2. Realized I needed to create my own cert, so added the server.https.cert and server.https.key options to my vite.config.ts
  3. Couldn't figure out why those weren't working, doublechecked the import paths, googled around, eventually landed here to find out that in order for those cert path options to get picked up, I had to go back and modify my dev script back to "dev": "npx vite", removing the --https

It's not exactly a bug, just wasn't very intuitive at first. It would be helpful if the docs stated somewhere that using an --https flag in the script would override any https options in the config, of if the config options just took priority over the flag.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants