Skip to content

Varnish Purge on Cloudways #7942

@Daniyal-DigitalOcean

Description

@Daniyal-DigitalOcean

Describe the bug
I am Senior Engineer from the Cloudways reporting an important issue which was recently observed with the wp-rocket and varnish purging. Cloudways has recently change their VCL where PURGE request will only work when the Real-IP header and request and is routed through the Nginx but on the Wp-rocket, The request is directly going on the varnish without the real IP header and PURGE request is getting blocked.

Working PURGE request:

*   << Request  >> 65581     
-   Begin          req 65580 rxreq
-   Timestamp      Start: 1764849175.476370 0.000000 0.000000
-   Timestamp      Req: 1764849175.476370 0.000000 0.000000
-   ReqStart       127.0.0.1 15930 a0
-   ReqMethod      PURGE
-   ReqURL         /.*
-   ReqProtocol    HTTP/1.0
-   ReqHeader      X-Real-IP: 127.0.0.1
-   ReqHeader      X-Forwarded-For: 127.0.0.1
-   ReqHeader      X-Client-Real-IP: 127.0.0.1
-   ReqHeader      Host: wordpress-1559331-6048096.cloudwaysapps.com
-   ReqHeader      X-Forwarded-Proto: http
-   ReqHeader      X-Forwarded-Host: wordpress-1559331-6048096.cloudwaysapps.com
-   ReqHeader      X-Application: wordpress
-   ReqHeader      X-App-User: vjjvvmutve
-   ReqHeader      X-Version: latest
-   ReqHeader      Connection: close
-   ReqHeader      User-Agent: W3 Total Cache
-   ReqUnset       X-Forwarded-For: 127.0.0.1
-   ReqHeader      X-Forwarded-For: 127.0.0.1, 127.0.0.1
-   VCL_call       RECV
-   ReqUnset       X-Forwarded-For: 127.0.0.1, 127.0.0.1
-   ReqHeader      x-forwarded-for: 127.0.0.1
-   ReqUnset       Host: wordpress-xxxx-xxxx.cloudwaysapps.com
-   ReqHeader      Host: wordpress-xxxx-xxxx.cloudwaysapps.com
-   VCL_return     purge
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       PURGE
-   VCL_return     synth
-   RespProtocol   HTTP/1.1
-   RespStatus     200
-   RespReason     OK
-   RespReason     Purged
-   RespHeader     Date: Thu, 04 Dec 2025 11:52:55 GMT
-   RespHeader     Server: Varnish
-   RespHeader     X-Varnish: 65581
-   VCL_call       SYNTH
-   RespHeader     Content-Type: text/html; charset=utf-8
-   RespHeader     Retry-After: 5
-   VCL_return     deliver
-   Timestamp      Process: 1764849175.476509 0.000139 0.000139
-   RespHeader     Content-Length: 0
-   Storage        malloc Transient
-   RespHeader     Accept-Ranges: bytes
-   RespHeader     Connection: close
-   Timestamp      Resp: 1764849175.476591 0.000221 0.000083
-   ReqAcct        356 0 356 211 0 211
-   End            

Request through WP-Rocket:

Begin          req 65573 rxreq
Timestamp      Start: 1764842237.777350 0.000000 0.000000
Timestamp      Req: 1764842237.777350 0.000000 0.000000
ReqStart       127.0.0.1 53716 a0
ReqMethod      PURGE
ReqURL         /page/.*
ReqProtocol    HTTP/1.1
ReqHeader      Host: http://wordpress-xxx-xxx.cloudwaysapps.com 
ReqHeader      User-Agent: WordPress/6.9; https://wordpress-xxx-xxx.cloudwaysapps.com 
ReqHeader      Accept: /
ReqHeader      Accept-Encoding: deflate, gzip, br, zstd
ReqHeader      X-Purge-Method: regex
ReqHeader      Connection: close
ReqHeader      X-Forwarded-For: 127.0.0.1
VCL_call       RECV
ReqUnset       X-Forwarded-For: 127.0.0.1
ReqHeader      x-forwarded-for:
VCL_return     synth
ReqUnset       Accept-Encoding: deflate, gzip, br, zstd
ReqHeader      Accept-Encoding: gzip
VCL_call       HASH
VCL_return     lookup
RespProtocol   HTTP/1.1
RespStatus     405
RespReason     Method Not Allowed
RespReason     This IP is not allowed to send PURGE requests.
RespHeader     Date: Thu, 04 Dec 2025 09:57:17 GMT
RespHeader     Server: Varnish
RespHeader     X-Varnish: 65574
VCL_call       SYNTH
RespHeader     Content-Type: text/html; charset=utf-8
RespHeader     Retry-After: 5
VCL_return     deliver
Timestamp      Process: 1764842237.777404 0.000054 0.000054
RespHeader     Content-Length: 0
Storage        malloc Transient
RespHeader     Connection: close
Timestamp      Resp: 1764842237.777443 0.000093 0.000039
ReqAcct        255 0 255 229 0 229
End

The reverse proxy configuration for Varnish should be set through port 80 so that all requests are routed through Nginx, ensuring the request headers—such as the real-ip header—are preserved as expected. Without this adjustment, thousands of users will be unable to use WP-Rocket on the new Cloudways servers. We also intend to apply this change to the older servers, so please prioritize and expedite this ticket to prevent any plugin compatibility issues.

Varnish VCL:

# PURGING
# SMART PURGE CACHE BY URL
if (req.method == "URLPURGE") {
        if (req.http.X-Real-IP != "127.0.0.1" && req.http.X-Real-IP != "::1" && req.http.X-Real-IP != "localhost" && req.http.X-Real-IP != "157.245.126.171") {
                return(synth(405, "This IP is not allowed to send PURGE requests."));
        }
        ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
        return(synth(200, "Purged"));
}

# PURGE CACHE BY HOSTNAME
if (req.method == "PURGE") {
        if (req.http.X-Real-IP != "127.0.0.1" && req.http.X-Real-IP != "::1" && req.http.X-Real-IP != "localhost" && req.http.X-Real-IP != "157.245.126.171") {
                return(synth(405, "Not allowed."));
        }
        ban("req.http.host ~ " + req.http.host);
        return (purge);
}

#BANING
if (req.method == "BAN") {
        if (req.http.X-Real-IP != "127.0.0.1" && req.http.X-Real-IP != "::1" && req.http.X-Real-IP != "localhost" && req.http.X-Real-IP != "157.245.126.171") {
                return(synth(405, "This IP is not allowed to send PURGE requests."));
        }
        ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
        return(synth(200, "Ban added"));
}

Metadata

Metadata

Labels

3rd party compatibilityIssues related to 3rd party compatibility like theme, plugin or hostingpriority: highIssues which should be resolved as quickly as possibleseverity: criticalDefect that prevents the testing/use of the software

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions