Should port 443 be open?

Port 443 is where HTTPS lives. When you type https://example.com, your browser opens a TCP connection to port 443 on the server’s IP address, then starts TLS on top of it. So:

  • If the machine serves a website or API over HTTPS, 443 must be open to the internet. There’s no safe way around it; that’s the job.
  • If it’s your laptop, desktop or home router and you don’t host anything, you don’t need 443 open inbound. Browsing uses outbound connections to other servers’ 443. Firewalls allow outbound traffic and the replies to it without any inbound rule.

The “firewall port 443” confusion is usually that distinction. Opening inbound 443 on a PC doesn’t make websites load better; it only matters if something on that PC is supposed to accept HTTPS connections.

Is an open 443 dangerous? Less than most ports, because it’s the one port everyone expects to be open and web servers are built for it. The risk is the software behind it. Keep it patched, and don’t expose admin panels on it that only you need. If you’re auditing the other ports on the same server, see risky open ports.

Check it from outside, not from the server

A port that’s “open” on the server can still be closed to the internet. Test from somewhere else.

The port check connects from outside your network. Enter example.com:443 to test just that port, or the bare hostname to test 15 common ports including 80, 443, 8080 and 8443. It waits 3 seconds per port. Open means a TCP connection was established. Closed covers both a refusal and silence, because the tool doesn’t distinguish them.

From another machine you can see the difference:

nc -vz -w 5 example.com 443
# Connection to example.com 443 port [tcp/https] succeeded!
# nc: connect to example.com port 443 (tcp) failed: Connection refused
# nc: connect to example.com port 443 (tcp) timed out: Operation now in progress

On Windows:

Test-NetConnection example.com -Port 443
# TcpTestSucceeded : True

nmap -Pn -p 443 example.com says open, closed or filtered, which maps to the same three cases.

How to read it:

  • Refused, instantly. The packets reached the machine and the OS answered “nobody here”. Nothing is listening on 443 on that address, or a firewall is set to REJECT. Start with the listener.
  • Timeout. Something dropped the packets on the way: a firewall, a cloud security group, the router, or the IP is wrong. Start with the network layers.
  • Open, but the browser still fails. The port isn’t your problem. Skip to the end.

Make sure you’re testing the right address. dig +short example.com A and dig +short example.com AAAA show what visitors are sent to. If the site has an AAAA record, test IPv6 separately (nc -6 -vz example.com 443); browsers prefer IPv6 when it’s available and only fall back to IPv4 when it fails, and it’s common for the IPv6 path to be firewalled differently.

Nothing is listening on 443

On the server:

sudo ss -ltnp 'sport = :443'
State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0      511          0.0.0.0:443       0.0.0.0:*     users:(("nginx",pid=812,fd=7))
LISTEN 0      511             [::]:443          [::]:*     users:(("nginx",pid=812,fd=8))

An empty result means no process is accepting connections on 443, and no firewall change will fix that. The usual reasons:

  • The web server isn’t running, or failed to start. systemctl status nginx and journalctl -u nginx -n 50 will usually say why; a missing certificate file is a classic.
  • It’s running but only configured for port 80. In nginx, look for a listen 443 ssl; line in the effective configuration: sudo nginx -T | grep -n 'listen'. In Apache, you need Listen 443 (normally in ports.conf, loaded with mod_ssl) and a <VirtualHost *:443> block.
  • Your application tries to bind 443 directly and isn’t allowed to. On Linux, ports below 1024 need root or the CAP_NET_BIND_SERVICE capability. A Node or Python app started as a normal user fails with EACCES or “permission denied”. Put a reverse proxy in front, or grant the capability.
  • Another process already holds 443, so your server fails with “address already in use”. ss shows which process it is.

Listening, but not where visitors connect

The Local Address column matters as much as whether a line is there at all.

  • 127.0.0.1:443 or [::1]:443 accepts connections from the machine itself only. Common with apps configured to listen('127.0.0.1') and Docker ports published as -p 127.0.0.1:443:443. Bind to 0.0.0.0 (or the public interface), or put a proxy that listens publicly in front.
  • [::]:443 without a 0.0.0.0:443 line. Whether that covers IPv4 depends on the software. nginx sets ipv6only=on by default, so listen [::]:443 ssl; on its own leaves IPv4 closed; add listen 443 ssl; as well.
  • A container listening inside Docker but not published. docker ps shows 0.0.0.0:443->443/tcp when it’s published; without a -p (or ports: in Compose), nothing outside the host can reach it.

The host firewall

If something listens on 0.0.0.0:443 and outside tests time out, the operating system’s firewall is the next suspect.

# Ubuntu / Debian with ufw
sudo ufw status verbose
sudo ufw allow 443/tcp

# RHEL, Rocky, Fedora with firewalld
sudo firewall-cmd --list-all
sudo firewall-cmd --permanent --add-service=https && sudo firewall-cmd --reload

# Raw iptables (not persistent across reboots on its own)
sudo iptables -L INPUT -n -v --line-numbers
sudo iptables -I INPUT -p tcp --dport 443 -j ACCEPT

On Windows Server:

New-NetFirewallRule -DisplayName "HTTPS in" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow

Look at the packet counters in iptables -L -v: a DROP rule whose counter rises each time you test is your answer. Also check that IPv6 is covered; ip6tables (or the inet family in nftables) is a separate rule set, and IPv4-only rules leave IPv6 closed.

The cloud firewall

Cloud servers have a second firewall outside the machine, and it’s the most common reason a correctly configured server times out.

  • AWS: the instance’s security group needs an inbound rule for TCP 443 from 0.0.0.0/0 (and ::/0 for IPv6). If the subnet has a custom network ACL, remember that NACLs are stateless: they need inbound 443 and outbound ephemeral ports (1024-65535) for the replies.
  • Google Cloud: a VPC firewall rule allowing tcp:443. The “Allow HTTPS traffic” checkbox at instance creation adds the https-server network tag that the default rule matches; a rule without the right tag or target doesn’t apply to the instance.
  • Azure: an inbound rule in the network security group on the NIC or subnet, with a priority that beats any deny rule.
  • Oracle Cloud: the VCN security list or NSG, and also the instance itself. Oracle’s platform images come with restrictive host firewall rules of their own, so opening the security list alone often isn’t enough.

If the server sits behind a load balancer, the load balancer needs a listener on 443 and the server’s security group needs to allow the load balancer. Visitors never reach the server’s 443 directly.

NAT, port forwarding and the ISP

For a server at home or in an office behind a router:

  • The router needs a port forward from external 443 to the server’s internal IP and port 443. Without it, the router has no idea where to send incoming connections.
  • Some routers use 443 themselves for remote management, which collides with the forward. Turn remote management off, or move it.
  • Some residential ISPs block inbound 80 and 443. Testing from outside shows a timeout even with everything else right; the ISP’s terms or support will confirm it.
  • If the WAN address shown on your router isn’t the address your public IP shows, or is in 100.64.0.0/10, you’re behind carrier-grade NAT. Inbound connections can’t reach you at all. Ask the ISP for a public IP, or use a tunnel service that connects outbound.

Port 443 is open, but HTTPS still fails

Then the problem is above TCP:

  • curl -v https://example.com reports wrong version number: something is listening on 443 but speaking plain HTTP. In nginx that’s listen 443; without ssl.
  • A certificate error, handshake failure or protocol error: run the SSL check to see the certificate and TLS version the server actually presents.
  • A redirect loop or an error status: the HTTP check follows the redirects and shows each response.

If the site is behind Cloudflare, the edge’s 443 is always open, and the interesting question is whether Cloudflare can reach your origin. Our port check doesn’t test Cloudflare addresses (it can’t open connections to them) and says so. Test the origin IP instead, and if Cloudflare shows an error page, see Cloudflare 522 or 525.

When 443 only fails from your network

If the outside check says open and the site loads on your phone’s mobile data, but not from your office or home connection, the block is on your side:

  • A corporate firewall or proxy that only allows approved sites, or inspects HTTPS.
  • Antivirus or “web protection” software that intercepts HTTPS.
  • A VPN or DNS filter that sends the name to a different address.

Here ERR_CONNECTION_TIMED_OUT, ERR_CONNECTION_REFUSED and ERR_CONNECTION_RESET cover the browser-side diagnosis.

After the fix

Run the outside check again for both IPv4 and IPv6, then load the site with curl -v https://example.com -o /dev/null and confirm you see Connected to, a TLS handshake and an HTTP status. If you changed iptables directly, make the rule persistent (netfilter-persistent save on Debian and Ubuntu, or your distribution’s equivalent) before the next reboot undoes it.

Check your own domain now

Free, no sign-up. Runs the exact check this guide describes and shows what to fix.