Subsequent discord launches never load with OpenVPN enabled

I’m recently coming back to NixOS after a long hiatus using Windows (out of convenience) and looking to ensure that my typical setup is working. I spent some time configuring OpenVPN to connect to ProtonVPN, which works great overall.

The one issue is that for some reason I haven’t been able to launch Discord properly while the VPN is configured. The first launch works fine, and nuking ~/.config/discord allows it to work again, at the cost of logging me out. But on any subsequent launches, it seems to hang on the “Starting” section.

At first I thought this was a Wayland issue, as I’m running niri, but manually commenting out my vpn config and rebuilding the OS seems to have solved the problem.

How can I get Discord and my VPN connection to play nicely together? Have I missed some crucial step?

For context, here are my flake.nix and configuration.nix, with the relevant VPN configuration already commented out for clarity. Here is the OpenVPN configuration file as well, with the more sensitive bits redacted: protonVPN_US-CA.conf - Pastebin.com .

Thanks in advance for any tips!

Try running it in a terminal so you get some logs.

Personally I recommend running discord in a browser instead. Electron is silly and for discord at least completely equivalent to a browser windiw.

Yeah, I’ve already logged successful and unsuccessful launches with the VPN enabled, and not seen anything too out of the ordinary between them. But you can see the latest run here:

[kolastor@warpcurrent:~]$ discord
[Nix] Disabling updates already done
Discord 0.0.111
(electron) 'session.getPreloads' is deprecated and will be removed. Please use 'session.getPreloadScripts' instead.
(electron) 'session.setPreloads' is deprecated and will be removed. Please use 'session.registerPreloadScript' instead.
Starting app.
Starting updater.
10/20/2025, 10:26:26 AM PDT [Modules] Modules initializing
10/20/2025, 10:26:26 AM PDT [Modules] Distribution: remote
10/20/2025, 10:26:26 AM PDT [Modules] Host updates: disabled
10/20/2025, 10:26:26 AM PDT [Modules] Module updates: enabled
10/20/2025, 10:26:26 AM PDT [Modules] Module install path: /home/kolastor/.config/discord/0.0.111/modules
10/20/2025, 10:26:26 AM PDT [Modules] Module installed file path: /home/kolastor/.config/discord/0.0.111/modules/installed.json
10/20/2025, 10:26:26 AM PDT [Modules] Module download path: /home/kolastor/.config/discord/0.0.111/modules/pending
splashScreen.initSplash(false)
CDM component API found
blackbox: 10/20/2025, 10:26:27 AM PDT 0

----------------------------------------------
CDM completed with status: cdm-ready-success
blackbox: 10/20/2025, 10:26:27 AM PDT 1 Discord starting: {"releaseChannel":"stable","version":"0.0.111"}, modulepath: /home/kolastor/.config/discord/0.0.111/modules
blackbox: 10/20/2025, 10:26:27 AM PDT 2 ✅ webContents.created web1 "index.html"
blackbox: 10/20/2025, 10:26:27 AM PDT 3 ✅ window.created win1 "discord"
(electron) 'console-message' arguments are deprecated and will be removed. Please use Event<WebContentsConsoleMessageEventParams> object instead.
10:26:27.102 › DiscordSplash.signalReady
splashScreen: SPLASH_SCREEN_READY
splashScreen.webContentsSend: SPLASH_SCREEN_QUOTE SPLASH_SCREEN_QUOTE [ 'Hold Tight — Loading Discord' ]
10/20/2025, 10:26:27 AM PDT [Modules] No updates to install
splashScreen: no-pending-updates
10/20/2025, 10:26:27 AM PDT [Modules] Host is up to date.
10/20/2025, 10:26:27 AM PDT [Modules] Checking for module updates at https://discord.com/api/modules/stable/versions.json
splashScreen: checking-for-updates
splashScreen.updateSplashState checking-for-updates checking-for-updates {}
splashScreen.webContentsSend: SPLASH_UPDATE_STATE SPLASH_UPDATE_STATE [ { status: 'checking-for-updates' } ]
10:26:27.124 › DiscordSplash.onStateUpdate: {"status":"checking-for-updates"}
10:26:27.124 › Splash.onStateUpdate: {"status":"checking-for-updates"}
blackbox: 10/20/2025, 10:26:27 AM PDT 4 ✅ webContents.did-finish-load web1
Error downloading with electron net: HTTP Error: Status Code 403
Falling back to node net library..
10/20/2025, 10:26:27 AM PDT [Modules] No module updates available.
splashScreen: update-check-finished true 0 false
splashScreen.launchMainWindow: false
Optional module ./ElectronTestRpc was not included.
Clearing GPU cache...
splashScreen.updateSplashState launching launching {}
splashScreen.webContentsSend: SPLASH_UPDATE_STATE SPLASH_UPDATE_STATE [ { status: 'launching' } ]
blackbox: 10/20/2025, 10:26:27 AM PDT 5 ✅ webContents.created web2 ""
10:26:27.600 › DiscordSplash.onStateUpdate: {"status":"launching"}
10:26:27.600 › Splash.onStateUpdate: {"status":"launching"}
Clearing code cache...
blackbox: 10/20/2025, 10:26:27 AM PDT 6 ✅ window.created win2 "Discord"
blackbox: 10/20/2025, 10:26:27 AM PDT 7 ✅ webContents.did-finish-load web2
10:26:28.102 › Splash.updateCountdownSeconds: undefined
10:26:29.102 › Splash.updateCountdownSeconds: undefined
10:26:30.102 › Splash.updateCountdownSeconds: undefined
10:26:31.102 › Splash.updateCountdownSeconds: undefined
10:26:32.102 › Splash.updateCountdownSeconds: undefined
10:26:33.102 › Splash.updateCountdownSeconds: undefined
10:26:34.102 › Splash.updateCountdownSeconds: undefined
10:26:35.102 › Splash.updateCountdownSeconds: undefined
10:26:36.102 › Splash.updateCountdownSeconds: undefined
10:26:37.102 › Splash.updateCountdownSeconds: undefined
10:26:38.102 › Splash.updateCountdownSeconds: undefined
10:26:39.102 › Splash.updateCountdownSeconds: undefined
10:26:40.102 › Splash.updateCountdownSeconds: undefined
10:26:41.102 › Splash.updateCountdownSeconds: undefined
10:26:42.102 › Splash.updateCountdownSeconds: undefined
10:26:43.102 › Splash.updateCountdownSeconds: undefined
10:26:44.102 › Splash.updateCountdownSeconds: undefined
10:26:45.102 › Splash.updateCountdownSeconds: undefined
10:26:46.102 › Splash.updateCountdownSeconds: undefined
10:26:47.102 › Splash.updateCountdownSeconds: undefined
10:26:48.102 › Splash.updateCountdownSeconds: undefined
10:26:49.102 › Splash.updateCountdownSeconds: undefined
10:26:50.102 › Splash.updateCountdownSeconds: undefined
10:26:51.102 › Splash.updateCountdownSeconds: undefined
10:26:52.102 › Splash.updateCountdownSeconds: undefined
10:26:53.102 › Splash.updateCountdownSeconds: undefined
10:26:54.102 › Splash.updateCountdownSeconds: undefined
10:26:55.102 › Splash.updateCountdownSeconds: undefined
10:26:56.102 › Splash.updateCountdownSeconds: undefined
10:26:57.102 › Splash.updateCountdownSeconds: undefined
10:26:58.102 › Splash.updateCountdownSeconds: undefined
10:26:59.102 › Splash.updateCountdownSeconds: undefined
10:27:00.102 › Splash.updateCountdownSeconds: undefined
10:27:01.102 › Splash.updateCountdownSeconds: undefined
10:27:02.102 › Splash.updateCountdownSeconds: undefined
10:27:03.102 › Splash.updateCountdownSeconds: undefined
10:27:04.102 › Splash.updateCountdownSeconds: undefined
10:27:05.102 › Splash.updateCountdownSeconds: undefined
10:27:06.102 › Splash.updateCountdownSeconds: undefined
10:27:07.102 › Splash.updateCountdownSeconds: undefined
10:27:08.102 › Splash.updateCountdownSeconds: undefined
10:27:09.102 › Splash.updateCountdownSeconds: undefined
10:27:10.102 › Splash.updateCountdownSeconds: undefined
10:27:11.102 › Splash.updateCountdownSeconds: undefined
blackbox: 10/20/2025, 10:27:11 AM PDT 8 window.close win1
blackbox: 10/20/2025, 10:27:11 AM PDT 9 webContents.destroyed web1
blackbox: 10/20/2025, 10:27:11 AM PDT 10 window.closed win1
blackbox: 10/20/2025, 10:27:17 AM PDT 11 before-quit
[4518:1020/102717.517908:ERROR:wayland_event_watcher.cc(47)] libwayland: warning: queue 0x1c6400a761c0 destroyed while proxies still attached:

[4518:1020/102717.518120:ERROR:wayland_event_watcher.cc(47)] libwayland:   wl_shm_pool#38 still attached

Where the window close events are from closing the window itself, and the wayland errors are from closing discord completely. But in general it just hangs on the Starting message splash without actually creating that second window, even though it claims to have done so previously.

I’ll rebuild my system without the VPN configuration again and grab a successful run as well, because that’s the one variable I haven’t checked (all my previous logging attempts just compared first runs with subsequent runs, all with the VPN enabled).

I’m sure using discord from the browser is fine, and I’ll opt for that in the meantime, but I’d still like to figure out what’s going on, even on principle.

I’ll rebuild my system without the VPN configuration again and grab a successful run as well

Here we are:

[kolastor@warpcurrent:~]$ discord
[Nix] Disabling updates already done
Discord 0.0.111
(electron) 'session.getPreloads' is deprecated and will be removed. Please use 'session.getPreloadScripts' instead.
(electron) 'session.setPreloads' is deprecated and will be removed. Please use 'session.registerPreloadScript' instead.
Starting app.
Starting updater.
10/20/2025, 10:42:17 AM PDT [Modules] Modules initializing
10/20/2025, 10:42:17 AM PDT [Modules] Distribution: remote
10/20/2025, 10:42:17 AM PDT [Modules] Host updates: disabled
10/20/2025, 10:42:17 AM PDT [Modules] Module updates: enabled
10/20/2025, 10:42:17 AM PDT [Modules] Module install path: /home/kolastor/.config/discord/0.0.111/modules
10/20/2025, 10:42:17 AM PDT [Modules] Module installed file path: /home/kolastor/.config/discord/0.0.111/modules/installed.json
10/20/2025, 10:42:17 AM PDT [Modules] Module download path: /home/kolastor/.config/discord/0.0.111/modules/pending
splashScreen.initSplash(false)
CDM component API found
blackbox: 10/20/2025, 10:42:17 AM PDT 0

----------------------------------------------
CDM completed with status: cdm-ready-success
blackbox: 10/20/2025, 10:42:17 AM PDT 1 Discord starting: {"releaseChannel":"stable","version":"0.0.111"}, modulepath: /home/kolastor/.config/discord/0.0.111/modules
blackbox: 10/20/2025, 10:42:17 AM PDT 2 ✅ webContents.created web1 ""
blackbox: 10/20/2025, 10:42:17 AM PDT 3 ✅ window.created win1 "discord"
(electron) 'console-message' arguments are deprecated and will be removed. Please use Event<WebContentsConsoleMessageEventParams> object instead.
10:42:17.783 › DiscordSplash.signalReady
splashScreen: SPLASH_SCREEN_READY
splashScreen.webContentsSend: SPLASH_SCREEN_QUOTE SPLASH_SCREEN_QUOTE [ 'Hold Tight — Loading Discord' ]
10/20/2025, 10:42:17 AM PDT [Modules] No updates to install
splashScreen: no-pending-updates
10/20/2025, 10:42:17 AM PDT [Modules] Host is up to date.
10/20/2025, 10:42:17 AM PDT [Modules] Checking for module updates at https://discord.com/api/modules/stable/versions.json
splashScreen: checking-for-updates
splashScreen.updateSplashState checking-for-updates checking-for-updates {}
splashScreen.webContentsSend: SPLASH_UPDATE_STATE SPLASH_UPDATE_STATE [ { status: 'checking-for-updates' } ]
10:42:17.830 › DiscordSplash.onStateUpdate: {"status":"checking-for-updates"}
10:42:17.830 › Splash.onStateUpdate: {"status":"checking-for-updates"}
blackbox: 10/20/2025, 10:42:17 AM PDT 4 ✅ webContents.did-finish-load web1
10/20/2025, 10:42:18 AM PDT [Modules] No module updates available.
splashScreen: update-check-finished true 0 false
splashScreen.launchMainWindow: false
Optional module ./ElectronTestRpc was not included.
Clearing GPU cache...
splashScreen.updateSplashState launching launching {}
splashScreen.webContentsSend: SPLASH_UPDATE_STATE SPLASH_UPDATE_STATE [ { status: 'launching' } ]
blackbox: 10/20/2025, 10:42:18 AM PDT 5 ✅ webContents.created web2 ""
10:42:18.144 › DiscordSplash.onStateUpdate: {"status":"launching"}
10:42:18.144 › Splash.onStateUpdate: {"status":"launching"}
Clearing code cache...
blackbox: 10/20/2025, 10:42:18 AM PDT 6 ✅ window.created win2 "Discord"
10:42:18.630 › [FAST CONNECT] wss://gateway.discord.gg/?encoding=etf&v=9&compress=zstd-stream, encoding: etf, version: 9
10:42:18.783 › Splash.updateCountdownSeconds: undefined
blackbox: 10/20/2025, 10:42:18 AM PDT 7 ✅ webContents.did-finish-load web2
10:42:18.901 › [libdiscore] [experiment_manager] Loaded experiments from cache
10:42:18.909 › [libdiscore] [BlockedDomainsStore] Deserialized 39460 hashes, revision 1969
10:42:19.008 › [KvStore] GuildStore initialized in mode: typescript
10:42:19.073 › [KkvStore] GuildRoleStore initialized in mode: typescript
10:42:19.135 › Initializing voice engine with audio subsystem: standard
10:42:19.214 › [KkvStore] RawGuildEmojiStore initialized in mode: typescript
10:42:19.285 › [DatabaseManager] active user changed (now: 201209005895450624, was: null, was: undefined)
legacyModuleUpdater: installed-module discord_krisp 1 1 true
legacyModuleUpdater: installed-module discord_game_utils 1 1 true
10:42:19.344 › [default] [BUILD INFO] Release Channel: stable, Build Number: 459631, Version Hash: e97e9b1f4ab6ffe3622e6377a0f9ad936f542b0a
10:42:19.496 › [KvStore] NoteStore initialized in mode: typescript
10:42:19.500 › [CloudSyncUtils] CloudSync is not supported on this platform
10:42:19.510 › [default] [NATIVE INFO] host 0.0.111, modules: discord_desktop_core: 1, discord_erlpack: 1, discord_spellcheck: 1, discord_utils: 2, discord_voice: 3, discord_zstd: 1, discord_krisp: 2, discord_game_utils: 1, discord_rpc: 1, build: null
mainScreen.UpdaterEvents: UPDATER_HISTORY_QUERY_AND_TRUNCATE
ipcMain.on(IPCEvents.APP_ASYNC_INDEX_TSX_LOADED) false false
splashScreen.pageReady
10:42:19.515 › [libdiscore] The answer for life the universe and everything is: 42
10:42:19.528 › [FAST CONNECT] connected in 892ms
10:42:19.531 › [Spellchecker] sh is not a valid locale.
blackbox: 10/20/2025, 10:42:19 AM PDT 8 window.close win1
blackbox: 10/20/2025, 10:42:19 AM PDT 9 webContents.destroyed web1
blackbox: 10/20/2025, 10:42:19 AM PDT 10 window.closed win1
10:42:19.888 › [MediaEngineStore] Failed to load Krisp module: Failed to setup Krisp module, error code: -3
mainScreen.UpdaterEvents: UPDATER_HISTORY_QUERY_AND_TRUNCATE
10:42:20.069 › [Spellchecker] Switching to en-US (available)
mainScreen.UpdaterEvents: UPDATER_HISTORY_QUERY_AND_TRUNCATE
legacyModuleUpdater: installed-module discord_rpc 1 1 true
mainScreen.UpdaterEvents: UPDATER_HISTORY_QUERY_AND_TRUNCATE
10:42:20.562 › [ConnectionStore] Socket is reconnecting because of starting new session
10:42:20.563 › [GatewaySocket] .connect() called, new state is WILL_RECONNECT
10:42:20.563 › [GatewaySocket] Setting connection state to WILL_RECONNECT
10:42:20.563 › [GatewaySocket] Setting connection state to CONNECTING
10:42:20.563 › [GatewaySocket] [CONNECT] wss://gateway.discord.gg, encoding: etf, version: 9, compression: zstd-stream
10:42:20.563 › [GatewaySocket] [FAST CONNECT] successfully took over websocket, state: [object Object]
10:42:20.564 › [GatewaySocket] [CONNECTED] wss://gateway.discord.gg/?encoding=etf&v=9&compress=zstd-stream in 0 ms
10:42:20.564 › [ConnectionStore] handleIdentify called [object Object]
10:42:20.564 › [GatewaySocket] Setting connection state to IDENTIFYING
10:42:20.565 › [GatewaySocket] [HELLO] via
gateway-prd-arm-us-east1-b-m81k: 0, heartbeat interval: 41250, took 2 ms
10:42:20.575 › [GatewaySocket] [IDENTIFY]
10:42:20.602 › [RPCServer:WSS] Starting on 6463
10:42:20.605 › [RPCServer:IPC] Starting on /run/user/1000/discord-ipc-0

// etc, etc.
// Definitely already successfully launched

Seems to be an issue with the electron request falling through? Not sure why the server is returning a 403 when it fails, because it’s definitely working on Firefox even with the VPN enabled. Maybe something to do with the way the headers are set up?

Probably. Discord may be more allergic to VPNs when their official client is used. Definitely not something that can be fixed on your end.

If you really want that app-feel, you may be interested in my nix-webapps. The main documented example is, in fact, discord ;p Currently only maintaining the linked branch, eventually I’ll get around to implementing the new API for chromium and just yanking main.