Bulk plugin installation from uploaded ZIP fails in MainWP 6.1.7

Could someone using the latest MainWP Dashboard version (6.1.7) please test whether bulk-installing a plugin by uploading a ZIP works? I get the following error:

PCLZIP_ERR_BAD_FORMAT (-10) : Unable to find End of Central Dir. Record signature"

On my setup, the ZIP uploads successfully, but the installation on the Child Sites fails. MainWP should provide the Child Sites with a signed ?sig=…&mwpdl=… download URL, but the download apparently never happens.

What I have checked:

  • The ZIP is successfully stored in /wp-content/uploads/mainwp/0/bulk/.

  • The relevant directories and files exist, so the upload itself works.

  • Direct access to that directory returns 403 because /uploads/mainwp/0/.htaccess contains deny from all, which appears to be intentional.

  • After a fresh installation attempt, no request containing mwpdl appeared in the web server access log.

  • A normal public ZIP URL on the same domain and server is accessible from the Child Sites.

  • Using the mainwp_installbulk_prepareupload filter to replace MainWP’s generated URL with that public ZIP URL makes the bulk installation work immediately.

  • I did not remove or modify the protective .htaccess file.

Based on an AI-assisted review of the MainWP 6.1.7 source code, the suspected issue is that the signed mwpdl URL may not be generated or passed to the Child Sites correctly. Another possibility is that a server, proxy, or WAF rule blocks this specific URL before it reaches WordPress.

Can anyone reproduce this with MainWP 6.1.7, or confirm that ZIP bulk installation still works normally on their setup?

I tested much more in the last hours but perhaps that is sufficient to figure out what’s going on here.

Thanks
Markus

This error mostly indicates that the zip was corrupted somehow or maybe incomplete.

I’ve just used this same function on 6.1.7 to update WP Rocket on a couple of sites that didn’t show the most recent update (needed to prevent a fatal error with WP 7.1) yet. And that worked fine, so I don’t think it’s MainWP itself.

I would start downloading the uploaded zip file and check if that’s still working fine.

I did not want to write every single step I tested into my first message, as it would be very long after many hours trial and error. No, it’s not a corrupted zip. I tested multiple times and I also downloaded a ZIP from another plugin e.g. Akismet to have a completely different test case. Failed all the time.

I actually also wanted to do the same with WP Rocket now. Initially though it was about installing a patched WPVivid version on many sites.

Good to see that it worked for you, so it means it’s not a global bug at least.

Hey @markus998

Do you have WPO365 Login, Solid Security, or another login/security layer running on the MainWP Dashboard?

We’ve seen this exact error when the signed ZIP download was intercepted by a security plugin and so the Child sites couldn’t fetch the file.

The .htaccess file is expected. The Child Site downloads the ZIP through a temporary signed URL instead of accessing the upload directory directly.

Can you temporarily deactivate the relevant Dashboard security layers and retry it on one Child Site?

No to the plugin solutions, only NinjaFirewall but I disabled it for testing on MainWP Dashboard site and selected child sites.

However, there is Cloudflare Zero Trust in place. I hope I memorize the name correctly. Basically, first I must authenticate with Cloudflare and receive a login link before I even get to WordPress login page to access MainWP.

I have this in place for approximately 2 years now. I thought I definitely did ZIP bulk upload successfully within the last 2 years in MainWP, however I can try to see how I can disable it again temporarily for testing.

Cloudflare Zero Trust is the issue in this case as it is applied on /wp-admin

I have no final solution yet (except for temporarily disabling it) but at least I know the source of the issue now.

The following snippet is not official!

I did not want to give up Cloudflare Trust Zero, because especially for something like MainWP an extra security layer is highly important.

However, the following code, e.g. added to WPCodeBox or another Code Snippet plugin or into functions.php applies a small change that can work around Cloudflare Zero Trust if the Cloudflare Zero Trust rule only applies to /wp-admin and /wp-login

This way the child sites can pull the zip file but Cloudflare Zero Trust still protects the login pages from MainWP Dashboard site

add_filter( 'mainwp_installbulk_prepareupload', function ( $urls ) {
    if (
        false === strpos( $urls, 'sig=' ) ||
        false === strpos( $urls, 'mwpdl=' )
    ) {
        return $urls;
    }

    return str_replace(
        admin_url( '?' ),
        home_url( '/?' ),
        $urls
    );
} );

Thanks for sharing @markus998 .

And glad to hear it’s working now for you.