Fixing WordPress cURL Error 7: Connection Refused on Localhost Port 80

intermediate๐Ÿ“ WordPress2026-06-16| WordPress 5.x+, Linux (Ubuntu/Debian/CentOS), Nginx, Apache, Docker environments.

Error Message

cURL error 7: Failed to connect to localhost port 80: Connection refused
#wordpress#curl#linux-administration#docker#troubleshooting

The ProblemYou open your Tools > Site Health page and see a bright red warning. WordPress reports that the REST API or loopback request failed. When you dig into the logs, you find this specific error:

cURL error 7: Failed to connect to localhost port 80: Connection refused

This isn't just a cosmetic issue. When cURL fails, your site loses its ability to perform essential background tasks. It can't check for plugin updates, it won't trigger scheduled posts (wp-cron), and it might even break your Gutenberg editor. Essentially, the server is trying to talk to itself, but the connection is being rejected.

Why Is This Happening?A "loopback request" occurs when WordPress sends an HTTP request back to its own server. If you get a "Connection refused" message, it usually points to one of four technical bottlenecks:

  • DNS Mismatch: The server tries to resolve localhost or your domain to 127.0.0.1, but your web service isn't listening on that specific IP.- Strict Firewalls: Security tools like UFW or IPTables are blocking traffic on the local loopback interface (lo).- Web Server Binding: Nginx or Apache is configured to listen only on your public IP, ignoring requests made to 127.0.0.1.- Docker Isolation: Inside a container, localhost refers to the container itself, not the host machine running your web server.## Step 1: Verify Connectivity via CLIStart by confirming the error from the server's perspective. SSH into your machine and run this command:
curl -I http://localhost:80

If the output says Connection refused, the problem lies within your OS or network configuration. However, if you see a 200 OK response here but still see the error in WordPress, the issue likely involves PHP-FPM or specific WordPress settings.

Step 2: Update the /etc/hosts FileYour server needs to know exactly where to send local requests. Often, it gets confused trying to resolve your domain name. Open your hosts file with sudo privileges:

sudo nano /etc/hosts

Ensure your domain is mapped to the local IP. If your site is example.com, your file should look like this:

127.0.0.1   localhost example.com
::1         localhost ip6-localhost ip6-loopback

Save the file and exit. This forces the server to look internally rather than trying to route the request out to the public internet and back.

Step 3: Check Web Server 'Listen' DirectivesIf your web server only listens on your public IP (e.g., 123.123.123.123), any request sent to 127.0.0.1 will be ignored.

For Nginx:Check your site configuration in /etc/nginx/sites-available/. Look for the listen directive:

server {
    listen 80; # This listens on all interfaces
    # Or explicitly add:
    listen 127.0.0.1:80;
    server_name localhost example.com;
}

For Apache:Check your ports.conf file or VirtualHost block. Ensure you aren't restricting the interface:

Listen 80

After making changes, restart your service: sudo systemctl restart nginx.

Step 4: Adjust Firewall RulesFirewalls often block the local loopback interface by default on hardened servers. If you use UFW on Ubuntu, allow traffic on the 'lo' interface with these commands:

sudo ufw allow in on lo
sudo ufw allow out on lo

For Firewalld users on CentOS or RHEL, add the interface to the trusted zone:

sudo firewall-cmd --permanent --zone=trusted --add-interface=lo
sudo firewall-cmd --reload

Step 5: Solutions for DockerIn Docker, localhost is isolated to the container. If WordPress is in one container and Nginx is in another, they can't see each other via localhost. The easiest fix is to use the service name from your docker-compose.yml.

If you cannot change the URL, add an extra_hosts entry to your WordPress service. This maps your domain to the Docker bridge IP (usually 172.17.0.1):

services:
  wordpress:
    extra_hosts:
      - "example.com:172.17.0.1"

Step 6: Bypass Proxy SettingsIf your server sits behind a corporate proxy, cURL might be trying to route local requests through that proxy. This usually ends in a timeout or refusal. Tell WordPress to ignore the proxy for local traffic by adding this line to your wp-config.php file:

define('WP_PROXY_BYPASS_HOSTS', 'localhost, 127.0.0.1, example.com');

VerificationHead back to Tools > Site Health. The "REST API" and "Loopback request" tests should now display a green "Passed" status. To be 100% sure, you can run a quick test via WP-CLI:

wp eval "$res = wp_remote_get('http://localhost/wp-json/'); echo is_wp_error($res) ? $res->get_error_message() : 'Connection Successful';"

Related Error Notes