Web Terminal - Connection error

I just wanted to test the new web terminal but I get a “Connection error.” shown - the console says

WebSocket connection to 'wss://cp.mydomain.de:8083/_shell/' failed: webTerminal.js:18 

Any further todo to get this new web terminal working?

(also tried adding a new firewall rule for port 8085)

Update 1: Ok, I see under the services that “web-terminal” is red (not started) and I can’t click the edit icon or the start icon there, nothing happens.

Update 2: In the terminal/console the # v-restart-service hestia-web-terminal command worked without any error and now the service is also green in the hestia list of services :+1:

Service is on but there is no link to the terminal anywhere/ How do you access it

1 Like

A hestia user (not admin!) has to be logged in - then this user has a new “terminal” icon right next to the file manager icon (at the top).

Have the same problem, my investigate showed that problem when accessing Hestia by domain (cp.mydomain.com:8083), but if login through 1.2.3.4:8083 terminal is working.
And this problem only on server that was upgraded from oldest version 1.8
If use fresh install web terminal works by domain.
But I not found solution.

Found Nginx Conf error, check this:
https://blog.lhl.one/artical/467.html

I have a similar problem - I unblocked the ports (although when I look at the nginx.conf service, the address is local) , set up the configuration files. When I restart the service, I have an error [20] in the log for the web terminal. When I enter the IP address x.x.x.x:8085, the browser only returns the message Upgrade Required (my system is up to date).

Domain.pl:3085 returns a problem with SSL, but this is normal because I do not have a certificate attached here.

In the Hesti panel, after entering the web terminal, I have a connection error message.

There is no need to add any rule to allow port 8085.

What did you do?

That doesn’t mean that your system must be upgraded, that means that the browser is trying to speak to the app in HTTP and the app requires WebSockets.

You should use the button >_ inside Hestia to access the web terminal. To view that icon the user must have assigned a shell like bash, jailbash, etc. all but nologin.

1 Like

If i try click on terminal icon in hestia panel i got error message “connection error”

Did you check the service and the log?

systemctl status hestia-web-terminal.service --no-pager -l

The log is here /var/log/hestia/nginx-error.log

Yes, I did check the status service and is running and active.

nginx-error.logo doesn’t show log with error web-terminal.

Show the output of this command:

lsof -Pn +c0 -i:8085 -sTCP:LISTEN

That’s really strange, I’ve simulated it and can see the error in the log:

2025/06/24 10:41:07 [error] 2204#0: *13 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.2.3, server: _, request: "GET /_shell/ HTTP/1.1", upstream: "http://[::1]:8085/_shell/", host: "h19u.lab.example.net:8083"
2025/06/24 10:41:07 [error] 2204#0: *13 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.2.3, server: _, request: "GET /_shell/ HTTP/1.1", upstream: "http://127.0.0.1:8085/_shell/", host: "h19u.lab.example.net:8083"

Thank you for the quick response.

Regarding the command lsof -Pn +c0 -i:8085 -sTCP:LISTEN, it returns:

COMMAND     PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
node    3967437 root   18u  IPv6 9511374      0t0  TCP *:8085 (LISTEN)

I’m running tail -f /var/log/hestia/nginx-error.log to view live logs, but when I click the terminal icon in Hestia CP, the error you mentioned doesn’t appear.

2025/06/24 10:23:32 [error] 2985107#0: *842 FastCGI sent in stderr: "PHP message: PHP Warning:  ini_set(): Session ini settings cannot be changed when a session is active in /usr/local/hestia/web/fm/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php on line 53" while reading response header from upstream, client: 60.32.43.1, server: _, request: "GET /fm/?r=/getconfig HTTP/2.0", upstream: "fastcgi://unix:/run/hestia-php.sock:", host: "example.com:38083", referrer: "https://example.com:38083/fm/"
2025/06/24 10:23:32 [error] 2985107#0: *842 FastCGI sent in stderr: "PHP message: PHP Warning:  ini_set(): Session ini settings cannot be changed when a session is active in /usr/local/hestia/web/fm/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php on line 53" while reading response header from upstream, client: 60.32.43.1, server: _, request: "GET /fm/?r=/getuser HTTP/2.0", upstream: "fastcgi://unix:/run/hestia-php.sock:", host: "example.com:38083", referrer: "https://example.com:38083/fm/"
2025/06/24 10:23:32 [error] 2985107#0: *842 FastCGI sent in stderr: "PHP message: PHP Warning:  ini_set(): Session ini settings cannot be changed when a session is active in /usr/local/hestia/web/fm/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php on line 53" while reading response header from upstream, client: 60.32.43.1, server: _, request: "POST /fm/?r=/getdir HTTP/2.0", upstream: "fastcgi://unix:/run/hestia-php.sock:", host: "example.com:38083", referrer: "https://example.com:38083/fm/"
2025/06/24 10:23:37 [error] 2985107#0: *842 FastCGI sent in stderr: "PHP message: PHP Warning:  ini_set(): Session ini settings cannot be changed when a session is active in /usr/local/hestia/web/fm/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php on line 53" while reading response header from upstream, client: 60.32.43.1, server: _, request: "POST /fm/?r=/logout HTTP/2.0", upstream: "fastcgi://unix:/run/hestia-php.sock:", host: "example.com:38083", referrer: "https://example.com:38083/fm/"
2025/06/24 10:23:37 [error] 2985107#0: *842 FastCGI sent in stderr: "PHP message: PHP Warning:  ini_set(): Session ini settings cannot be changed when a session is active in /usr/local/hestia/web/fm/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php on line 53" while reading response header from upstream, client: 60.32.43.1, server: _, request: "GET /fm/?r=/getuser HTTP/2.0", upstream: "fastcgi://unix:/run/hestia-php.sock:", host: "example.com:38083", referrer: "https://example.com:38083/fm/"
2025/06/24 10:23:38 [error] 2985107#0: *842 FastCGI sent in stderr: "PHP message: PHP Warning:  ini_set(): Session ini settings cannot be changed when a session is active in /usr/local/hestia/web/fm/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php on line 53" while reading response header from upstream, client: 60.32.43.1, server: _, request: "POST /fm/?r=/getdir HTTP/2.0", upstream: "fastcgi://unix:/run/hestia-php.sock:", host: "example.com:38083", referrer: "https://example.com:38083/fm/"

That’s is all - last 10 errors.

Do you access the panel using https://yourServerHostname:8083 or are you using an external proxy (CDN)?

I changed default port on 38083 and working well. I don’t use proxy.

Hi everyone,

I recently changed the port for HestiaCP’s web terminal, and now I see a message saying “upgrade required”, which I don’t fully understand. Since HestiaCP is free and open-source, I’m unsure why this appears.

I want to revert the web terminal to its default port, but I can’t find any documentation about what that default port actually is. Could someone clarify this for me?

Appreciate your help!

Hi @DGA,

Please, don’t reply to the three posts asking the same question.

That error message refers to HTTP error code 426 (Upgrade Required). In this case, it occurs because you are trying to use HTTP to communicate with a WebSocket used by the web terminal.

The default port is 8085. Why you want to change it?

Just Sorry….

The code searches for TRUSTED IPs with TRUSTED ports or HOSTNAME:PORT that are set by onboard utilities through incorrect holes. You will see everything for yourselves now.

/usr/local/hestia/web-terminal/server.js (You can get it through sudo systemctl status hestia-web-terminal.service -l)

const wss = new WebSocketServer({
        port: parseInt(config.WEB_TERMINAL_PORT, 10),
        verifyClient: async (info, cb) => {
                if (!info.req.headers.cookie.includes(sessionName)) { // Markup 1
                        cb(false, 401, 'Unauthorized');
                        return;
                }

                const origin = info.origin || info.req.headers.origin; // Markup 2
                let matches = origin === `https://${hostname}:${config.BACKEND_PORT}`;  // Markup 3

                if (!matches) {
                        for (const ip of Object.keys(systemIPs)) {
                                if (origin === `https://${ip}:${config.BACKEND_PORT}`) { // Markup 4
                                        matches = true;
                                        break;
                                }
                        }
                }
                if (matches) {
                        cb(true);
                        return;
                }
                cb(false, 403, 'Forbidden'); // Markup 5 
        },
});

This is what the code that causes the connection problem looks like.
For convenience, I have marked the lines that interest us.

  1. We won’t dwell on 1 for long; this is where you usually get a 401 error. If you have this error, you need to go to the forum for failed hackers.

  2. is the line that your user enters in the browser hoping to reach your Gravitsapa (web panel). For example, panel.example.com.

  3. Let’s look further. The script compares what the user entered with this king-of-the-hill construction := hostname (which you entered in Settings → Configure → Basic Options → Hostname) and the service port it is looking for in the hestiacp config. (Did you think you could name the machine something other than the domain name? Naive.)
    Of course, in most cases it doesn’t find it (this is where all the proxy lovers drop out lol), but we move on.

  4. It searches for a list of system IPs, assigns a port from the config by analogy with 3, and looks at the dropped socket with a blank stare, giving it a 403 error. IMPORTANT. This will only work normally if your server is NOT behind NAT (if we are talking about access via IP:Port). It takes the IP addresses of the machine’s network adapters.

  5. Here you get your forbidden and end up in this thread.

It would seem, what could be the solution? Engineering and invention

  1. sudo nano /usr/local/hestia/web-terminal/server.js

const wss = new WebSocketServer({
        port: parseInt(config.WEB_TERMINAL_PORT, 10),
        verifyClient: async (info, cb) => {
                if (!info.req.headers.cookie.includes(sessionName)) {
                        cb(false, 401, 'Unauthorized');
                        return;
                }

                const origin = info.origin || info.req.headers.origin;
                let matches = origin === `https://${hostname}:${config.BACKEND_PORT}`;

                if (!matches) {
                        for (const ip of Object.keys(systemIPs)) {
                                if (origin === `https://${ip}:${config.BACKEND_PORT}`) {
                                        matches = true;
                                        break;
                                }
                        }
                }

                if (!matches && origin === `https://${config.THRUSTED_DOMAIN}`) {
                        matches = true;
                }

                if (matches) {
                        cb(true);
                        return;
                }
                cb(false, 403, 'Forbidden');
        },
});

  1. Apply it sudo systemctl restart hestia-web-terminal.service
  2. Make it legit sudo nano /usr/local/hestia/bin/v-list-sys-config
    Find somesing like that.
                        "VERSION": "'$VERSION'",
                        "WEBMAIL_ALIAS": "'$WEBMAIL_ALIAS'",
                        "WEBMAIL_SYSTEM": "'$WEBMAIL_SYSTEM'",
                        "WEB_BACKEND": "'$WEB_BACKEND'",
                        "WEB_PORT": "'$WEB_PORT'",
                        "WEB_RGROUPS": "'$WEB_RGROUPS'",
                        "WEB_SSL": "'$WEB_SSL'",
                        "WEB_SSL_PORT": "'$WEB_SSL_PORT'",
                        "WEB_SYSTEM": "'$WEB_SYSTEM'",
                        "WEB_TERMINAL": "'$WEB_TERMINAL'",
                        "WEB_TERMINAL_PORT": "'$WEB_TERMINAL_PORT'", # DONT FORGET THIS COMMA
                        "THRUSTED_DOMAIN" : "'$THRUSTED_DOMAIN'"  #Add this string
                }
        }'
}

# Shell list

  1. Make it configurable sudo nano /usr/local/hestia/conf/hestia.conf
WEB_SSL='openssl'
WEB_SSL_PORT='443'
WEB_SYSTEM='nginx'
WEB_TERMINAL_PORT='8085'
WEB_TERMINAL='true'
THRUSTED_DOMAIN='example.com' # Add this string and replace placeholder with your domain (add port if you not brave enought)
  1. At least, make it alive sudo systemctl restart hestia

Enjoy.

Hestia has these strict checks in place for security reasons. Locking the terminal down to the system hostname and local IPs makes sure it’s only accessible through the official panel, which helps prevent unauthorized remote access and CSRF attacks. Bypassing that logic basically puts the server’s integrity at risk just for convenience.

But hey, it’s your server, you can do whatever you want :wink:

Enjoy.

2 Likes