Website Not Loading on a Cloud VM? Start Here

Aybars Altınyay
Aybars Altınyay
Platform Engineer & Technical Writer
Updated Sep 23, 202614 min read
Written for: Beginners and developers debugging websites, apps, or self-hosted services on a Linux cloud VM.
TroubleshootingLinuxNginxDNSFirewallWeb ServerCloud VM
Last reviewed:
Guide
Website Not Loading on a Cloud VM? Start Here
rafftechnologies.com/learn
On this page

Key Takeaways

Start debugging from the outside in: DNS, ports, firewall, web server, application, and logs. A website can fail even when the VM is healthy. Port 80 and 443 must be open at the cloud, firewall, and service level. Logs usually show the real failure faster than guessing.

A website not loading on a cloud VM usually fails because one layer in the request path is broken: DNS, network access, firewall rules, web server status, application process, or logs. For beginners, the mistake is often checking those layers randomly instead of following a repeatable order.

Raff Technologies users often deploy websites, APIs, dashboards, and self-hosted tools on Linux VMs. When something does not load in the browser, the VM itself may still be healthy. The problem may be outside the server, inside the server, or between the web server and the application.

A website request is a chain: domain name → DNS record → public IP → open port → firewall → web server → application → response. This guide gives you a practical checklist for debugging that chain on a Linux cloud VM. The examples assume Ubuntu 24.04 and Nginx, but the same thinking applies to Apache, Caddy, Node.js, Python, PHP, Docker, and most self-hosted applications.

The Debugging Order That Saves Time

The fastest way to debug a website that will not load is to move from the outside toward the application. Start with what the user's browser sees, then move into DNS, ports, firewall rules, web server status, app processes, and logs.

This order matters because website failures can look similar from the browser. "This site can't be reached," "connection refused," "connection timed out," "502 Bad Gateway," and "404 Not Found" all point to different layers.

Use this order because it separates public-internet problems from server-side problems before changing configuration files. Guessing too early often creates a second problem on top of the first one.

Use this checklist before reinstalling Nginx, changing DNS again, or resizing the VM.

SymptomMost likely layer
Domain does not resolveDNS
IP works but domain does notDNS record or propagation
Connection timed outFirewall, closed port, or service not listening
Connection refusedPort reachable, but no service is accepting traffic
404 Not FoundWeb server reached, wrong site block or document root
502 Bad GatewayReverse proxy reached, backend app failed
403 ForbiddenPermissions, index file, or access rule
SSL warningCertificate, domain mismatch, or HTTPS config
Slow loadingApp performance, database, disk, memory, or network

Start With the Exact Error Message

The browser error message gives the first clue. Do not skip it.

Open the site in a browser and write down the exact error. Then test both the domain and the public IP address.

Bash
curl -I http://your-domain.com curl -I http://YOUR_SERVER_IP

The -I flag asks for only the HTTP headers. This is useful because you can quickly see whether the server replies at all.

Expected output for a working HTTP site may look like this: HTTP/1.1 200 OK Server: nginx Content-Type: text/html

A redirect to HTTPS is also normal: HTTP/1.1 301 Moved Permanently Location: https://your-domain.com/

If the IP works but the domain fails, the server is probably not the problem. Start with DNS.

If both the IP and the domain fail, continue down the checklist.

Check DNS Before Editing the Server

DNS tells the internet which IP address your domain should use. If DNS points to the wrong IP, the browser never reaches your Raff VM.

Check the domain's A record:

Bash
dig +short your-domain.com

You should see your VM's public IPv4 address: 203.0.113.10

You can also check the full DNS response:

Bash
dig your-domain.com

Look for the ANSWER SECTION. If the IP is missing, wrong, or still points to an old server, update the A record at your DNS provider.

For www, check it separately:

Bash
dig +short www.your-domain.com

A common beginner mistake is setting the root domain but forgetting www, or setting www but forgetting the root domain.

A basic DNS setup usually looks like this:

HostTypeValue
@AYour VM public IP
wwwCNAMEyour-domain.com
apiAYour VM public IP, if needed

Tip: DNS changes can take time to propagate. If you recently changed records, test with dig and wait before making unrelated server changes.

Confirm the VM Is Reachable

Before debugging the website stack, confirm that your VM is online and reachable.

From your local machine, test the IP:

Bash
ping YOUR_SERVER_IP

Some servers block ICMP ping, so a failed ping is not always proof that the VM is down. A better test is to check whether SSH responds:

Bash
ssh your-user@YOUR_SERVER_IP

If SSH works, the VM is online.

If SSH does not work, the website issue may be part of a broader access problem. Check whether the VM is running, whether the IP is correct, and whether your firewall allows SSH.

For recovery access, browser-based console access can help when SSH is unavailable. Raff's VNC console article explains how to access a VM from the browser when normal remote access is not working:

Access Your VM Anywhere With Our New VNC Console

Check Whether Ports 80 and 443 Are Open

A website usually needs port 80 for HTTP and port 443 for HTTPS. If those ports are closed, the server may be healthy but unreachable from the browser.

From your local machine, test HTTP:

Bash
curl -I http://YOUR_SERVER_IP

Then test HTTPS:

Bash
curl -I https://your-domain.com

You can also test ports with nc:

Bash
nc -vz YOUR_SERVER_IP 80 nc -vz YOUR_SERVER_IP 443

A successful connection looks like this: Connection to YOUR_SERVER_IP 80 port [tcp/http] succeeded!

A failed connection may show: Connection timed out

or: Connection refused

These errors mean different things.

ErrorMeaning
Connection timed outTraffic is likely blocked by a firewall or network rule
Connection refusedServer is reachable, but no service is listening on that port
SSL certificate errorHTTPS is reachable, but the certificate or hostname is wrong

This is why port testing is useful. It tells you whether the request reaches the server before you start editing application files.

Check the Server Firewall

On Ubuntu, many beginners use UFW. A firewall can block HTTP and HTTPS even when Nginx is configured correctly.

Check UFW status:

Bash
sudo ufw status verbose

A web server should usually allow SSH, HTTP, and HTTPS: Status: active To Action From

22/tcp ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere

If port 80 or 443 is missing, allow them:

Bash
sudo ufw allow 80/tcp sudo ufw allow 443/tcp

Then reload UFW:

Bash
sudo ufw reload

Verify again:

Bash
sudo ufw status verbose

Warning: Do not reset firewall rules blindly on a remote server. Always keep SSH access allowed before reloading firewall rules, or you may lock yourself out.

For broader security planning, read:

Cloud Security Fundamentals

Check Whether the Web Server Is Running

If the firewall allows traffic but the website still does not load, check whether the web server is running.

For Nginx:

Bash
sudo systemctl status nginx

A healthy service shows: Active: active (running)

If Nginx is stopped, start it:

Bash
sudo systemctl start nginx

Enable it to start after reboot:

Bash
sudo systemctl enable nginx

For Apache:

Bash
sudo systemctl status apache2

For Caddy:

Bash
sudo systemctl status caddy

If the service fails to start, do not guess. Check the logs:

Bash
sudo journalctl -u nginx --no-pager -n 50

For Apache:

Bash
sudo journalctl -u apache2 --no-pager -n 50

For Caddy:

Bash
sudo journalctl -u caddy --no-pager -n 50

A common mistake is editing a configuration file, restarting the service, and then missing the exact error message. journalctl usually tells you which line or file caused the failure.

Confirm the Service Is Listening on the Right Port

A running web server still needs to listen on the correct port.

Use ss to check listening ports:

Bash
sudo ss -tulpn

Look for lines like this: tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6)) tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1234,fd=7))

If nothing is listening on port 80 or 443, your browser cannot reach a website on those ports.

If another process is already using port 80, Nginx may fail to start. Find the process:

Bash
sudo lsof -i :80

or:

Bash
sudo ss -tulpn | grep ':80'

Only one service can listen on the same IP and port combination. For example, Apache and Nginx cannot both listen on port 80 unless you configure them carefully with different addresses or ports.

Test the Web Server Configuration

Configuration syntax errors are common after editing Nginx site files.

Test Nginx:

Bash
sudo nginx -t

A successful test looks like this: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

If there is an error, Nginx prints the file and line number. Fix that exact issue before restarting.

After a successful test, reload Nginx:

Bash
sudo systemctl reload nginx

For Apache, test the configuration with:

Bash
sudo apache2ctl configtest

A successful Apache result looks like this: Syntax OK

Do not restart repeatedly before testing syntax. A config test is faster, safer, and tells you where the problem is.

Check the Nginx Server Block

If the server responds but shows the wrong site, a default page, or a 404, check the Nginx server block.

List enabled sites:

Bash
ls -l /etc/nginx/sites-enabled/

Open your site configuration:

Bash
sudo nano /etc/nginx/sites-available/your-site

A simple static site server block may look like this:

Nginx
server { listen 80; server_name your-domain.com www.your-domain.com; root /var/www/your-site; index index.html; location / { try_files $uri $uri/ =404; } }

Check these fields carefully:

FieldWhat to verify
listenUses port 80 or 443 as expected
server_nameMatches your domain and www version
rootPoints to the correct document directory
indexMatches the actual index file
try_filesDoes not route requests incorrectly

If you change the file, test and reload:

Bash
sudo nginx -t sudo systemctl reload nginx

A common beginner mistake is editing a file in sites-available but forgetting to link it into sites-enabled.

Create the symlink if needed:

Bash
sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/

Then test and reload Nginx.

Check File Paths and Permissions

A 403 error often means the web server reached the site but cannot read the files.

Check the document root:

Bash
ls -la /var/www/your-site

Make sure the index file exists:

Bash
ls -la /var/www/your-site/index.html

Check directory permissions:

Bash
sudo find /var/www/your-site -type d -exec chmod 755 {} \; sudo find /var/www/your-site -type f -exec chmod 644 {} \;

Set ownership to the web user if appropriate:

Bash
sudo chown -R www-data:www-data /var/www/your-site

Warning: Do not use chmod 777 to "fix" permission problems. It may make the error disappear, but it creates an unsafe setup.

For application deployments, the correct owner may differ. A static site can often be owned by www-data, while a Node.js or Python app may run under its own service user.

Check the Application Process

If Nginx works but returns 502 Bad Gateway, the web server probably cannot reach the backend application.

For example, a Node.js, Python, FastAPI, Django, or Rails app may run behind Nginx on a local port such as 3000, 5000, or 8000.

Check whether the app is running:

Bash
sudo ss -tulpn | grep -E '3000|5000|8000'

If your app is managed by systemd:

Bash
sudo systemctl status your-app

Check the app logs:

Bash
sudo journalctl -u your-app --no-pager -n 100

Common causes of 502 Bad Gateway include:

  • the app process is stopped
  • the app listens on a different port
  • the app listens on 127.0.0.1 but Nginx points elsewhere
  • environment variables are missing
  • the app crashed during startup
  • file permissions prevent the app from reading required files
  • the database connection failed

A simple reverse proxy block may look like this:

Nginx
location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }

Make sure the proxy_pass port matches the actual application port.

Check Web Server Logs

Logs usually reveal the real cause faster than changing settings randomly.

For Nginx access logs:

Bash
sudo tail -n 50 /var/log/nginx/access.log

For Nginx error logs:

Bash
sudo tail -n 100 /var/log/nginx/error.log

Watch logs live while refreshing the browser:

Bash
sudo tail -f /var/log/nginx/error.log

If you see requests in access.log, traffic is reaching Nginx. If you do not see requests, the issue may still be DNS, firewall, or networking.

Common log clues:

Log messageLikely meaning
connect() failed (111: Connection refused)Backend app is not running or wrong port
permission deniedFile or socket permission problem
no such file or directoryWrong file path or missing document root
host not found in upstreamBad upstream name or DNS issue
directory index is forbiddenMissing index file or disabled directory listing

Do not read only the last line. Look at the error just before the failure.

Check HTTPS and Certificates

If HTTP works but HTTPS fails, the problem is likely SSL/TLS configuration.

Test HTTPS:

Bash
curl -Iv https://your-domain.com

Common HTTPS problems include:

  • certificate issued for the wrong domain
  • certificate expired
  • Nginx not listening on port 443
  • firewall blocking port 443
  • missing certificate files
  • redirect loop between HTTP and HTTPS
  • app forcing HTTPS behind a proxy without correct headers

If you use Let's Encrypt with Certbot, check certificates:

Bash
sudo certbot certificates

Test renewal:

Bash
sudo certbot renew --dry-run

If the certificate is missing, confirm DNS works before requesting a new one. Let's Encrypt must be able to verify the domain.

Tip: Do not debug HTTPS before HTTP works. First make sure http://your-domain.com reaches the correct server, then add HTTPS.

Check DNS Caching and Local Browser Issues

Sometimes the server is fixed but your browser, DNS resolver, or local network still has old information.

Test from another network or device.

You can also use public DNS resolvers:

Bash
dig @1.1.1.1 your-domain.com +short dig @8.8.8.8 your-domain.com +short

If public resolvers show the correct IP but your computer does not, clear local DNS cache or wait for the old record to expire.

Also test with curl:

Bash
curl -I http://your-domain.com

Browser extensions, cached redirects, and old HTTPS/HSTS behavior can create confusing results. Command-line tests usually give cleaner signals.

Check Resource Limits

If the site loads sometimes but fails under traffic, check CPU, RAM, disk, and service restarts.

Check memory:

Bash
free -h

Check disk usage:

Bash
df -h

Check the largest directories:

Bash
sudo du -h --max-depth=1 /var | sort -h

Check active processes:

Bash
top

or install htop:

Bash
sudo apt update sudo apt install htop htop

A full disk can break web servers, databases, SSL renewal, deployments, and log writing. Low memory can cause application processes or databases to be killed.

If the workload has outgrown the VM, review the current plan and decide whether to resize. You can compare VM options on the Raff Linux VM page and review costs on Raff pricing.

Use a Short Decision Tree

When a website does not load, use this order:

CheckCommandWhat success looks like
DNSdig +short your-domain.comReturns your VM IP
HTTP responsecurl -I http://your-domain.comReturns HTTP headers
Open portsnc -vz IP 80Connection succeeds
Firewallsudo ufw status verbose80 and 443 allowed
Web serversudo systemctl status nginxActive running
Listening portssudo ss -tulpnNginx listens on 80/443
Config syntaxsudo nginx -tSyntax OK
App processsudo systemctl status your-appActive running
Logstail -f /var/log/nginx/error.logShows real errors
Resourcesdf -h, free -h, topDisk/RAM/CPU not exhausted

The point is not to memorize commands. The point is to remove uncertainty one layer at a time.

Common Mistakes Beginners Make

The most common website debugging mistake is changing several things at once. If you change DNS, firewall rules, Nginx config, app ports, and SSL settings in one session, you may fix one problem while creating another.

Avoid these mistakes:

  • changing DNS before confirming the current IP
  • opening firewall ports without checking the service
  • restarting Nginx without running nginx -t
  • debugging HTTPS before HTTP works
  • ignoring logs
  • assuming a 502 is an Nginx problem
  • using chmod 777 to fix permissions
  • forgetting the www DNS record
  • pointing Nginx to the wrong app port
  • not checking disk space

A good debugging session should leave notes. Record what you tested, what changed, and what result you saw.

Raff-Specific Context

On Raff, most beginner website deployments start with a Linux VM. That gives you a clean environment for Nginx, Apache, Caddy, Docker, Node.js, Python, PHP, databases, and self-hosted tools.

Raff Linux VMs include root access, NVMe SSD storage, DDoS protection, firewall management, snapshots, automated backups, private networking, and web console access. These features do not replace application debugging, but they give you the infrastructure tools needed to investigate safely.

For a simple public website, choose the smallest Raff VM class that safely meets the workload's CPU, memory, storage, and traffic needs. Use the live pricing page for current plan sizes and prices rather than relying on a value embedded in this troubleshooting guide.

Before making risky changes, create a snapshot or backup. If you break Nginx, delete the wrong site file, or change the wrong firewall rule, a recovery point can save time.

For broader server setup, read:

Your First Cloud Server: What to Do After You Provision It

For command reference while debugging, read:

Linux Commands for Cloud Servers

Conclusion

A website that will not load is easier to debug when you treat it as a chain instead of a mystery. Start with DNS, then test public ports, firewall rules, web server status, listening services, configuration syntax, app processes, logs, HTTPS, and system resources.

The most useful habit is moving from the outside in. If the domain points to the wrong IP, Nginx does not matter yet. If port 80 is blocked, the app is not the first problem. If Nginx returns 502, the backend app deserves attention before you edit DNS again.

On a Raff Linux VM, you have the tools to debug each layer: SSH access, web console recovery, firewall controls, snapshots, backups, and enough flexibility to run the stack your project needs.

Start with one failing layer, verify it, fix it, and move to the next one. That is how debugging becomes manageable.

Was this article helpful?
Aybars Altınyay
Aybars Altınyay
Platform Engineer & Technical Writer

Aybars is a Platform Engineer & Technical Writer at Raff Technologies. He works on Linux VM templates, self-hosted application workflows, and security-focused deployment validation, turning tested infrastructure procedures into clear, practical tutorials for developers and teams.

Put it into practice

Spin up a Raff server, follow the steps above on real infrastructure, and you are live. Linux or Windows, backed by a 14-day money-back guarantee.

Frequently asked questions

Why is my website not loading on a cloud VM?
Most failures come from DNS, closed ports, firewall rules, a stopped web server, broken app process, or incorrect Nginx configuration.
How much does it cost to host a website on Raff?
Raff VM pricing can change independently of this troubleshooting guide. Use the live Raff pricing page to compare current General Purpose and CPU-Optimized VM options for the website you plan to run.
Should I check DNS or the server first?
Check both, but start from the outside in: domain DNS, public IP, open ports, firewall, web server, app process, and logs.
What ports should be open for a website?
Public websites usually need port 80 for HTTP and port 443 for HTTPS. SSH should be limited to port 22 or your custom SSH port.
What logs should I check when a website fails?
Start with web server logs, systemd service logs, application logs, and authentication logs if access or permission issues are suspected.