Skip to content Skip to sidebar

This thread is resolved. Here is a description of the problem and solution.

Problem:
You are trying to update the WPML SEO plugin but encounter an error message: 'Download failed. Method Not Allowed.' This issue occurs across multiple websites.
Solution:
If you're experiencing this issue, we recommend checking the AWS CAPTCHA triggers. In this case, they were responsible for generating too many requests from the server's IP address, leading to HTTP 405 errors.

Please note that this solution might be outdated or not applicable to your specific case. We highly recommend checking related known issues at https://wpml.org/known-issues/, verifying the version of the permanent fix, and confirming that you have installed the latest versions of themes and plugins. If the problem persists, please open a new support ticket at WPML support forum.

This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

Tagged: 

This topic contains 24 replies, has 0 voices.

Last updated by Bruno Kos 1 week, 5 days ago.

Assisted by: Bruno Kos.

Author Posts
July 23, 2025 at 7:37 am #17262072

martinR-5

Same here, long time WPML user. But update of WPML SEO 2.2.1. failed today.

July 23, 2025 at 8:19 am #17262553

John-Pierre Cornelissen

@Bruno, I am still waiting to get the secure form to provide server access.

As you can see, there are now three more people reporting the same issue. That looks more and more an issue with your infrastructure.

July 23, 2025 at 8:20 am #17262556

oliverR-28

Same here, update of WPML SEO 2.2.1. failed with "Method Not Allowed", three sites.

July 23, 2025 at 9:58 am #17263034

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

Based on our system diagnostics, there doesn’t appear to be any issue with how the websites are communicating with our servers. For this reason, our developers are now investigating whether the problem might be coming from within our installer. I’ll keep you updated as soon as we have more information.

July 23, 2025 at 12:37 pm #17263949

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

I activated the private reply for the cPanel access.

July 23, 2025 at 1:52 pm #17264325

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

I understand your hosting provider mentioned they don’t see Imunify360 blocking the request. However, our 2nd-tier support has recommended verifying this more specifically.

Could you please ask your hosting provider to check if Imunify360 or any mod_security rules might be interfering with outgoing requests to wpml.org or its subdomains?
If possible, they could also try temporarily disabling Imunify360 just for requests to wpml.org to see if the issue resolves.

Sometimes these firewalls may block requests without clearly logging them, so a direct test would help us rule this out completely.

Let me know what they say, and we can go from there.

July 23, 2025 at 2:36 pm #17264520

John-Pierre Cornelissen

Hi,

Ref. Check if Imunify360 or any mod_security rules interfering with outgoing requests to wpml.org or its subdomains?

» Can you let me know what exact request they should try? Because they tried with the terminal before and you said it was an invalid request.
» Or, you have access to cPanel, so you could try yourself with the terminal that's available in there. ***

Ref. disabling Imunify360 just for requests to wpml.org to see if the issue resolves.
» They can't/won't. It's on shared hosting and they already said that they can't whitelist your domain nor make any exceptions. I also can't disable it for just my account.
» Thy asked me to test with ModSecurity disabled, which I did. That didn't solve the issue.

*** If I copy the url that is displayed in WP when the update fails, it correctly downloads the zip file. If I use the same url in the terminal it fails. Here is the command that I used (I have masked sensitive information)

[XXX ~]$ wget -P /home/XXX/ "https://wpml.org/?download=3566177&version=2.2.2&site_key=XXX&site_url=https%3A%2F%2Fwpml.XXX.nl&wpml_version=4.7.6"

--2025-07-23 16:28:22-- https://wpml.org/?download=3566177&version=2.2.2&site_key=XXX&site_url=https%3A%2F%2Fwpml.XXX.nl&wpml_version=4.7.6
Resolving wpml.org (wpml.org)... 44.199.32.10, 44.205.120.116
Connecting to wpml.org (wpml.org)|44.199.32.10|:443... connected.
HTTP request sent, awaiting response... 405 Not Allowed
2025-07-23 16:28:23 ERROR 405: Not Allowed.

»» so the Terminal request get's connected but receives error 405.
AI: The 405 error indicates that the server recognizes the URL you're trying to access, but it doesn't allow the specific HTTP method you're using to interact with that URL

July 24, 2025 at 2:02 pm #17267790

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

We were able to successfully update the plugins on your site, but we cannot definitively say what resolved the issue, as multiple variables were involved. Here's what we attempted and observed:

What We Did:

* Disabled ModSecurity from cPanel temporarily (left it off overnight).
* During testing, we encountered AWS CAPTCHA triggers, likely due to too many requests from the server IP, which caused HTTP 405 errors.
* There was also a wrong site key used initially, which could have contributed to the issue.
* We suspect Imunify360 (security layer on hosting) may also have had some influence when combined with ModSecurity, but we cannot confirm that 100%.

What We Recommend:

* The issue seems related to rate-limiting or CAPTCHA protection on AWS. You can test this yourself using the PHP script below to simulate a request and inspect response headers.
* If the response headers include `x-amzn-waf-action: captcha`, it confirms you're being rate-limited by AWS.

Diagnostic Script:

You can run the following script on your server to check for AWS rate limiting or other header-based blocks:

<?php
// === CONFIGURE THIS URL ===
$url = 'https://wpml.org/'
     . '?download=3566177'
     . '&version=2.2.2'
     . '&site_key=03b907753d'
     . '&site_url=' . rawurlencode('<em><u>hidden link</u></em>')
     . '&wpml_version=4.7.6';

// ——————————————————————————————————————————————————————————
// 1) Perform the cURL request and capture outgoing headers + response
// ——————————————————————————————————————————————————————————
function testCurl(string $url): array {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_FAILONERROR    => false,                    // so we still get body
        CURLOPT_HEADER         => true,                     // include response headers
        CURLOPT_VERBOSE        => true,
        CURLOPT_STDERR         => fopen('<em><u>hidden link</u></em>', 'rw+'),
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,    // try 1.1 here
        CURLOPT_USERAGENT      => 'PHP/' . PHP_VERSION,
    ]);
    // ask cURL to tell us what it sends
    curl_setopt($ch, CURLINFO_HEADER_OUT, true);

    $raw = curl_exec($ch);
    $info = curl_getinfo($ch);
    // fetch sent headers
    $sent = $info['request_header'] ?? '[no header_out]';
    // split headers/body
    $hdrSize = $info['header_size'];
    $respHdr = substr($raw, 0, $hdrSize);
    $respBody= substr($raw, $hdrSize);
    curl_close($ch);

    return [
        'sent'      => $sent,
        'resp_code' => $info['http_code'],
        'resp_hdr'  => $respHdr,
        'resp_body' => substr($respBody, 0, 500) . (strlen($respBody)>500?"\n…":""),
    ];
}

// ——————————————————————————————————————————————————————————
// 2) Perform the PHP streams request and capture outgoing headers + response
// ——————————————————————————————————————————————————————————
function testStreams(string $url): array {
    // build context identical to file_get_contents() defaults
    $opts = [
      'http' => [
        'method'           => 'GET',
        'header'           => "User-Agent: PHP/" . PHP_VERSION . "\r\n",
        'protocol_version' => 1.1,    // try 1.1 here to match cURL
        'ignore_errors'    => true,   // get 4xx/5xx body
      ]
    ];
    $ctx = stream_context_create($opts);

    // grab response
    $body = @file_get_contents($url, false, $ctx);

    // $http_response_header is set by file_get_contents()
    $sentHdr = implode("\r\n", [
        "GET " . parse_url($url, PHP_URL_PATH)
            . (parse_url($url, PHP_URL_QUERY) ? '?' . parse_url($url, PHP_URL_QUERY) : '')
            . " HTTP/1.1",
        "Host: " . parse_url($url, PHP_URL_HOST),
        "User-Agent: PHP/" . PHP_VERSION,
        ""  // trailing CRLF
    ]) . "\r\n";

    // reconstruct response headers
    $respHdr = is_array($http_response_header)
        ? implode("\r\n", $http_response_header) . "\r\n"
        : '[no headers]';

    // streams don't tell us code directly; parse it
    preg_match('#^HTTP/\d+\.\d+\s+(\d+)#', $http_response_header[0] ?? '', $m);
    $code = $m[1] ?? '[unknown]';

    return [
        'sent'      => $sentHdr,
        'resp_code' => $code,
        'resp_hdr'  => $respHdr,
        'resp_body' => substr($body ?? '', 0, 500) . (strlen($body)>500?"\n…":""),
    ];
}

// ——————————————————————————————————————————————————————————
// 3) Run both tests
// ——————————————————————————————————————————————————————————
$curl    = testCurl($url);
$streams = testStreams($url);

// ——————————————————————————————————————————————————————————
// 4) Output side‑by‑side for diff
// ——————————————————————————————————————————————————————————
echo "<style> body{font-family:monospace;} .box{border:1px solid #ccc;padding:10px;margin:10px;} .col{display:inline-block;vertical-align:top;width:48%;}</style>";
echo "<div class='col box'><h2>cURL → sent</h2><pre>"
   . htmlspecialchars($curl['sent']) . "</pre>\n"
   . "<h2>cURL ← {$curl['resp_code']}</h2><pre>"
   . htmlspecialchars($curl['resp_hdr']) . "</pre>\n"
   . "<h2>Body (first 500 chars)</h2><pre>"
   . htmlspecialchars($curl['resp_body']) . "</pre></div>";

echo "<div class='col box'><h2>Streams → sent</h2><pre>"
   . htmlspecialchars($streams['sent']) . "</pre>\n"
   . "<h2>Streams ← {$streams['resp_code']}</h2><pre>"
   . htmlspecialchars($streams['resp_hdr']) . "</pre>\n"
   . "<h2>Body (first 500 chars)</h2><pre>"
   . htmlspecialchars($streams['resp_body']) . "</pre></div>";

Let us know if you’d like us to investigate further.

July 24, 2025 at 2:41 pm #17268151

John-Pierre Cornelissen

Awesome, thank you for fixing this Bruno!

I could also successfully update WPML on all 12 sites on this specific server now.

Thanks again.
JP

---

Feedback on what you did and might have caused the problems

* Disabled ModSecurity from cPanel temporarily (left it off overnight).
» I did that before, it didn't help and I also didn't have to do it with the other sites that run on this server, so I doubt that this has been the issue.

* There was also a wrong site key used initially, which could have contributed to the issue.
» no there wasn't. The original site key allows me to update WPML Multilingual CMS from v4.7.4 to v4.7.5 on 28 May 25. You suggested on July 10 it could be the site key, and back then I de-registered and re-registered with the site key mentioned in my account. It didn't help. Then I generated a new site key, it still didn't fix it. Then on July 14 you tried your own site key but that didn't fix it either. Lastly, 12 sites were affected by this issue. All are updated now without changing site keys, so safe to say that wasn't the issue.

* We suspect Imunify360 (security layer on hosting) may also have had some influence when combined with ModSecurity, but we cannot confirm that 100%.
» I doubt that has been the reason. Disable ModSecurity didn't fix it, the hosting provider said your domain isn't blocked and another server with the same hosting provider and the same Imunify360 didn't have the issue.

* During testing, we encountered AWS CAPTCHA triggers, likely due to too many requests from the server IP, which caused HTTP 405 errors.
» Considering all of the above, it looks like this has been the issue.

+ I see there was a new version too. The original issue happened when updating v2.1.1 to v2.2.1, and the current version is v2.2.2.

July 25, 2025 at 8:32 am #17270315

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+02:00)

I'm glad we were able to identify the root cause of the issue.

For other clients experiencing similar problems, we recommend checking the AWS CAPTCHA triggers. In this case, they were responsible for generating too many requests from the server's IP address, leading to HTTP 405 errors.