Refreshing Items

Troubleshooting Loopback Requests (Self-cURL)

Sometimes a website needs to “call itself” to trigger background work. In Speedy's case it needs to be able to make a quick web request back to your site, specifically a URL of a previously cached page, in an attempt to refresh the page after the cache has been cleared. On most hosts this works automatically, but some server settings block it. When that happens, Speedy’s background refreshes won’t run even though pages load fine in your browser. This guide explains what’s happening, how to recognize it, and the simplest ways to fix it yourself or with your host’s help.

When viewing the Cache Clearing Rules page, Speedy will attempt to determine if these loopback requests will work. If not, you will see the following alert. If you see this alert, add $config['speedy_enable_logging'] = 'yes'; to your config.php file, then attempt to clear and refresh a cache item. Visit the Tools > System Logs > Developer in your ExpressionEngine control panel where you should see some help debugging logs.

What is a loopback request?

Speedy triggers an internal URL on your site to start work. That means PHP (running under your web server) must be allowed to open an outgoing HTTPS/HTTP connection to your own domain or to localhost. If the server forbids outbound connections, misroutes the domain, or disables required PHP features, the request won’t go through and the refresh never starts.

Symptoms

  • Speedy actions appear to do nothing or “hang,” but your site loads normally.

  • A cache item is cleared, but it is not automatically regenerated.

  • Background refreshes do not start after you trigger them.

  • Your host confirms the site is up, but server-side calls to your own domain fail.

Common causes (plain language)

  • Your ExpressionEngine site is offline (resulting in a 503 HTTP response)

  • A security policy on the server forbids the website from making any outgoing network connections (common on managed or locked‑down servers).

  • The firewall blocks traffic from the server to itself (including to port 80/443).

  • Your domain resolves to an address (often IPv6) that the web server is not listening on.

  • Access rules or a Web Application Firewall (WAF) deny requests from the server’s own IP.

  • PHP features needed for making requests are turned off (for example, cURL or URL fopen).

A simple message for your hosting provider

Share this text with your host or server admin:

Our site uses a loopback request to https://example.com to start background tasks. Please confirm the web server/PHP user is allowed to make outbound HTTP/HTTPS connections to its own domain, localhost (127.0.0.1), and the server’s public IP. If SELinux is enabled, please set httpd_can_network_connect=on. If AppArmor is used, permit network access for php-fpm/apache. Ensure the firewall allows outbound TCP 80/443 (including hairpin to the host’s own IP). Also verify PHP’s cURL extension is enabled, allow_url_fopen is On, and that the web server listens on the same IP versions (IPv4/IPv6) our DNS returns.

Replace example.com with your domain.

Quick checks (optional)

If you have shell access, your host can quickly confirm:

  • Try a request as the web user: sudo -u www-data curl -I https://your-domain (Debian/Ubuntu) or sudo -u apache curl -I https://your-domain (RHEL family).

  • Compare results to curl -I http://127.0.0.1/ and to your server’s public IP. If localhost works but the public domain fails, the issue is usually firewall, DNS/IPv6, or a WAF rule.

  • Check that PHP’s cURL is enabled and allow_url_fopen is On.

Fixes (what usually needs changing)

These are common, safe adjustments your host can make.

SELinux (RHEL/CentOS/Rocky/Alma)

  • Allow outbound connections from the web server: setsebool -P httpd_can_network_connect 1

  • Confirm status with getenforce/sestatus and getsebool httpd_can_network_connect.

AppArmor (Ubuntu/Debian)

  • Permit network access in the AppArmor profile for php-fpm/apache2.

  • Your host can temporarily move the profile to “complain” mode to verify, then update it permanently.

Firewall and networking

  • Allow outbound traffic on TCP ports 80 and 443, including to the server’s own public IP and to 127.0.0.1.

  • Some setups block “hairpin” connections (from the server to its own public IP). Allow these, or have Speedy reach localhost with the correct Host header.

DNS and IP versions (IPv4/IPv6)

  • Ensure your domain resolves to IPs the web server actually listens on. If DNS returns only IPv6 but the server is not bound to IPv6, either add an IPv4 A record or enable IPv6 on the server.

Web server ACL/WAF rules

  • Include the server’s own IP and localhost as permitted sources in allow/deny rules.

  • If behind a CDN/WAF, make sure origin rules don’t block requests that originate from the server itself.

PHP configuration

  • Enable the cURL extension for PHP if you want the cURL‑based methods available.

  • Set allow_url_fopen = On if you want the PHP streams methods available.

  • If you rely on the system curl command, ensure exec() is not disabled in disable_functions and that curl is installed.

After fixing

  • Re‑run your Speedy action (for example, clearing or refreshing) and confirm it completes.

  • If problems persist, ask your host to verify that DNS resolution and web server bindings match (IPv4/IPv6), and that no firewall/WAF rule blocks the server from calling its own domain.

Last updated

Was this helpful?