Upgrade 4.18.1.SP1 - 4.18.2: Validator “Restore” returned fail status

When trying to upgrade I get the following:

Validation issue

Validator “Restore” returned fail status

File
Unable to prepare restore script.

For add-ons that you can skip “create backup” they upgrade ok. But the core updates that you can’t skip the backup, this error has me stuck.

The config.local.php has this as far as file permissions go:

// Default permissions for newly created files and directories
define('DEFAULT_FILE_PERMISSIONS', 0666);
define('DEFAULT_DIR_PERMISSIONS', 0777);

However, the upgrades folder’s permissions are 0755 and the source_restore.php has 0666.

The folders that are created inside the upgrades folder (eg core_4.18.1.SP1-4.18.2) gets permissions 0755. It’s files, get permissions 0644.

Now, I tried changing the config.local.php and used this:

// Default permissions for newly created files and directories
define('DEFAULT_FILE_PERMISSIONS', 0644);
define('DEFAULT_DIR_PERMISSIONS', 0755);

Which matched the permissions of the folders and files that are being created but the result is the same.

Please note that Inside the upgrades folder, the folder core_4.18.1.SP1-4.18.2 is being created and it contains the following PHP file: restore_2024-11-15_11-53-41.php

It’s an Nginx server using PHP-FPM. PHP version is 8.1

----Added Notes—
Found the upgrade log in /var/upgrade (core_log.txt)

################################################################################
################################################################################
2024-11-15 11:59:25: Starting installation of the "core" upgrade package
2024-11-15 11:59:25: Upgrading version 4.18.1.SP1 to 4.18.2
2024-11-15 11:59:25: Running as user "owner"
2024-11-15 11:59:25: Storing entry point files permissions...
2024-11-15 11:59:25: index.php ==> 33184 (-rw-r-----)
2024-11-15 11:59:25: admin-cp.php ==> 33184 (-rw-r-----)
2024-11-15 11:59:25: api.php ==> 33184 (-rw-r-----)
2024-11-15 11:59:25:  ==> 16888 (drwxrwx---)
2024-11-15 11:59:25: Executing pre-upgrade validators
2024-11-15 11:59:25: Found 0 validators at package
2024-11-15 11:59:25: Executing "collisions" validator
2024-11-15 11:59:25: Executing "permissions" validator
2024-11-15 11:59:25: Executing "restore" validator
2024-11-15 11:59:25: Backup filename is "upg_core_4.18.1.SP1-4.18.2_15Nov2024_115925"
2024-11-15 11:59:25: Preparing restore script
2024-11-15 11:59:25: Upgrades directory permissions: drwxrwxrwx owner:owner
2024-11-15 11:59:25: Source restore script permissions: -rw-rw-rw- owner:owner
2024-11-15 11:59:25: Directory "/home/owner/htdocs/***.*******.***/upgrades/core_4.18.1.SP1-4.18.2/" for restore script already created
2024-11-15 11:59:25: Created restore script at "/home/owner/htdocs/***.*******.***/upgrades/core_4.18.1.SP1-4.18.2/restore_2024-11-15_11-59-25.php"
2024-11-15 11:59:25: Restore script permissions: -rw-r--r-- owner:owner
2024-11-15 11:59:25: Correcting target restore script directory permissions...
2024-11-15 11:59:25: ----------
2024-11-15 11:59:25: Changing permissions of "/home/owner/htdocs/***.*******.***/upgrades/core_4.18.1.SP1-4.18.2/" to 755
2024-11-15 11:59:25: Using chmod()... OK
2024-11-15 11:59:25: ----------
2024-11-15 11:59:25: Target restore script directory permissions: drwxr-xr-x owner:owner
2024-11-15 11:59:25: Correcting upgrades directory permissions...
2024-11-15 11:59:25: ----------
2024-11-15 11:59:25: Changing permissions of "/home/owner/htdocs/***.*******.***/upgrades" to 755
2024-11-15 11:59:25: Using chmod()... OK
2024-11-15 11:59:25: ----------
2024-11-15 11:59:25: Upgrades directory permissions: drwxr-xr-x owner:owner
2024-11-15 11:59:25: Checking restore script availability via HTTP/HTTPS
2024-11-15 11:59:25: Restore script is NOT available via HTTP at "https://***.*******.***/upgrades/core_4.18.1.SP1-4.18.2/restore_2024-11-15_11-59-25.php".
2024-11-15 11:59:25: Upgrade stopped: unable to prepare restore file.

Have you read the following article?

Hello,

Yes I’ve read it. That’s why I posted the contents of config.local.php. That’s the reason I tried changing the permissions on the files too. No luck…

Please check the other paragraphs there, about cURL, the upgrades directory, the source_restore.php.

Hello,

I’ve checked the upgrades directory. It’s there. Also the source_restore.php. It’s there too.

Now as for the curl:

  • cURL-related problems:
    • cURL isn’t installed on the server.
      • cURL is installed on the server.
    • сURL returns an empty response body.
      • Not sure how to test that
    • The responses to cURL requests return errors.
      • I don’t see any errors on the logs or on the log I uploaded but still I am not sure if I can do something else to test that
    • Loopback connection is prohibited on the server, which leads to the following error:
      HTTP error: curl (56): Failure when receiving data from the peer
      • I don’t see that error anywhere. I might not be checking the right log files. But still I am not sure how to test that

Would it be too much trouble to help me verify that the curl is or isn’t the cause of the issue?

Please try checking the response that is being returned by cURL request:

<?php

error_reporting(E_ALL);
ini_set('display_errors', 'on');

$url = 'http://example.domain/upgrades/core_4.18.1.SP1-4.18.2/restore_2024-11-15_11-59-25.php';

list($result_curl, $errno, $error) = fn_curl_request($url);

if(!empty($error)) {
  fn_print_r("Error $errno: $error");
  if (!empty($result_curl['headers'])) {
    fn_print_r("Headers: " . $result_curl['headers']);
  }
} else {
  fn_print_r($result_curl['content'], $result_curl['headers']);
}

function fn_curl_request($url){

    $ch = curl_init();
    
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, true);

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_STDERR, $f = fopen(__DIR__ . '/curl_dbg.txt', "a+"));

    $content = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);

    fclose($f);

    if (!empty($content)) {
      list($headers, $content) = _parseContent($content);
      $result_curl['headers'] = $headers;
    }
    $result_curl['content'] = $content;

    return array($result_curl, $errno, $error);
}

function _parseContent($content)
{
    while (strpos(ltrim($content), 'HTTP/') === 0) {
        list($_headers, $content) = preg_split("/(\r?\n){2}/", $content, 2);
    }

    return array($_headers, $content);
}

function fn_print_r()
{
    $args = func_get_args();

    fn_echo('<ol style="font-family: Courier; font-size: 12px; border: 1px solid #dedede; background-color: #efefef; float: left; padding-right: 20px;">');
    foreach ($args as $v) {
	fn_echo('<li><pre>' . htmlspecialchars(print_r($v, true)) . "\n" . '</pre></li>');
    }
    fn_echo('</ol><div style="clear:left;"></div>');
}


function fn_echo($value)
{
    echo($value);
    
    fn_flush();
}

function fn_flush()
{
    if (function_exists('ob_flush')) {
        @ob_flush();
    }

    flush();
}

Update the domain so that it will point to the domain of your store in the code:

$url = 'http://example.domain/upgrades/core_4.18.1.SP1-4.18.2/restore_2024-11-15_11-59-25.php';

Place this script into the root folder of your installation, and access it via browser. Check its results and also the contents of the curl_dbg.txt file generated inside the root folder of your installation.

1 Like

Hello.
Thank you for the reply.

I got a 403 forbidden page and curl_dbg.txt file got the contents.

When I removed the cloudflare proxy, the 403 forbidden was thrown from the nginx server and curl_dbg.txt was not created. I got the curl_dbg.txt ONLY with passthrough/proxy through cloudflare.

The result is quite big. Want me to post it here?

In this case, I recommend that you contact your server administrator and look into this issue. The script should not return 403, this is definitely related to the nginx configuration.

While trying to troubleshoot or avoid this 403 forbidden from the server I tried adding this in my vhost file:

  location ~ ^/(\w+/)?(\w+/)?upgrades/ {
    allow all;
  }

But that didn’t fix it… can’t think of any reason this PHP returns “forbidden”

Are you using the config provided in our documentation?
https://docs.cs-cart.com/latest/install/nginx.html

Hello,

I tried to incorporate most directives mentioned there when I set up the website. However, more configuration was needed so I can’t really copy and paste the exact suggestion. So here is my nginx config. Do you see an issue on it?

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name domain.com;
  return 301 https://www.domain.com$request_uri;
}

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name www.domain.com www1.domain.com;
  {{root}}

  {{nginx_access_log}}
  {{nginx_error_log}}

  if ($scheme != "https") {
    rewrite ^ https://$host$uri permanent;
  }

  location ~ /.well-known {
    auth_basic off;
    allow all;
  }

  {{settings}}

  location / {
    {{varnish_proxy_pass}}
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_hide_header X-Varnish;
    proxy_redirect off;
    proxy_max_temp_file_size 0;
    proxy_connect_timeout      720;
    proxy_send_timeout         720;
    proxy_read_timeout         720;
    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;
    proxy_temp_file_write_size 256k;
    add_header 'Referrer-Policy' 'origin';
  }
  
  

  location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
    add_header Access-Control-Allow-Origin "*";
    expires max;
    access_log off;
  }

  if (-f $request_filename) {
    break;
  }
}

server {
  listen 8080;
  listen [::]:8080;
  server_name www.domain.com www1.domain.com;
  {{root}}

  try_files $uri $uri/ /index.php?$args;
  index index.php index.html;

  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS "on";
    fastcgi_param SERVER_PORT 443;
    fastcgi_pass 127.0.0.1:{{php_fpm_port}};
    fastcgi_param PHP_VALUE "{{php_settings}}";
  }

  if (-f $request_filename) {
    break;
  }
}

Hello,

Do you think you can help with this error? is there an issue on my vhost?

This block can be related to the issue. Please try to adjust the config from the documentation for your server.

Hello,

I’ve tried but I’m unable to merge the two configurations. I can’t figure out how to add the config from the documentation to the config on my server. Can you please help?

I mean… what values should I add and on which subsection?

I tried to create a new configuration but I’m hesitant to try it out. Could you please revise it and tell me if there are any suggestions or adjustments that can be made?

I will then apply it based on your suggestions:

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name herokids.gr;
  return 301 https://www.herokids.gr$request_uri;
}

server {
  listen 80;
  listen [::]:80;
  listen 443 ssl http2;
  listen [::]:443 ssl http2;
  {{ssl_certificate_key}}
  {{ssl_certificate}}
  server_name www.herokids.gr www1.herokids.gr;
  {{root}}
  {{nginx_access_log}}
  {{nginx_error_log}}

  # Ensure HTTPS is enforced
  if ($scheme != "https") {
    return 301 https://$host$request_uri;
  }

  # Compression settings
  gzip on;
  gzip_disable "msie6";
  gzip_comp_level 6;
  gzip_min_length 1100;
  gzip_buffers 16 8k;
  gzip_proxied any;
  gzip_types text/plain application/xml application/javascript text/css text/xml application/json application/xml+rss;

  # Client settings
  client_max_body_size 100m;
  client_body_buffer_size 128k;
  client_header_timeout 3m;
  client_body_timeout 3m;
  send_timeout 3m;
  client_header_buffer_size 1k;
  large_client_header_buffers 4 16k;

  # Main location block
  location / {
    index index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$args;
    {{varnish_proxy_pass}}
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_hide_header X-Varnish;
    proxy_redirect off;
    proxy_max_temp_file_size 0;
    proxy_connect_timeout 720;
    proxy_send_timeout 720;
    proxy_read_timeout 720;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    proxy_temp_file_write_size 256k;
    add_header 'Referrer-Policy' 'origin';
  }

  # CS-Cart API rewrites
  location ~ ^/(\w+/)?(\w+/)?api/ {
    rewrite ^/(\w+/)?(\w+/)?api/(.*)$ /api.php?_d=$3&ajax_custom=1&$args last;
    rewrite_log off;
  }

  # Restrict access to sensitive directories
  location ~ ^/(\w+/)?(\w+/)?(var|app|design|images|js)/ {
    return 404;
    location ~* \.(tpl|php.?)$ {
      return 404;
    }
  }

  # Handle well-known location for SSL validation
  location ~ /.well-known {
    auth_basic off;
    allow all;
  }

  # Static file handling
  location ~* \.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
    add_header Access-Control-Allow-Origin "*";
    expires max;
    access_log off;
  }

  # Prevent direct access to PHP files
  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS "on";
    fastcgi_param SERVER_PORT 443;
    fastcgi_pass 127.0.0.1:{{php_fpm_port}};
    fastcgi_param PHP_VALUE "{{php_settings}}";
  }

  # Cache settings for static assets
  location ~* \.(jpe?g|jpg|webp|ico|gif|png|css|js|pdf|txt|tar|woff|woff2|svg|ttf|eot|csv|zip|xml|yml)$ {
    access_log off;
    expires max;
    add_header Access-Control-Allow-Origin "*";
    add_header Cache-Control public;
  }

  # Restrict access to initialization files
  location ~ ^/(\w+/)?(\w+/)?init.php {
    return 404;
  }

  # Block access to hidden files
  location ~ /\.(ht|git) {
    return 404;
  }
}

server {
  listen 8080;
  listen [::]:8080;
  server_name www.herokids.gr www1.herokids.gr;
  {{root}}
  try_files $uri $uri/ /index.php?$args;
  index index.php index.html;

  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_intercept_errors on;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    try_files $uri =404;
    fastcgi_read_timeout 3600;
    fastcgi_send_timeout 3600;
    fastcgi_param HTTPS "on";
    fastcgi_param SERVER_PORT 443;
    fastcgi_pass 127.0.0.1:{{php_fpm_port}};
    fastcgi_param PHP_VALUE "{{php_settings}}";
  }
}

Hi!

I recommend you to contact your hosting support or your server administrator on this case.

Thanks for the reply.

The support of the server does not take these changes as part of their responsibility

I, the administrator, am the only one responsible for these changes.

As you see I can code and make changes and I came up with a config that might work. I need you to check if I made all the necessary changes before deploying it.

There is nobody else. I’m at the top of the ladder, and I need help figuring this out. Just to note, nobody else has figured it out for my hosting environment yet. Solving this will help other people who use CloudPanel.io to use cs-cart on their installations. So please, work with me on this one.

I’m afraid I can’t help you with this. All I can recommend is that you try to set up the server as described in our documentation. Or we can set up the server for you from scratch on a paid basis. Please let me know if you are interested.