Can not initiate remote transfer. Error message: ‘transferStatus’

CyberPanel Remote Backup Transfer Bug Fix

Problem Description

When attempting to transfer websites between two fresh CyberPanel servers using the Remote Backups feature (:8090/backup/remoteBackups), users encounter the following error:

Can not initiate remote transfer. Error message: 'transferStatus'

Or alternatively:

Can not initiate remote transfer. Error message: API request contains potentially dangerous characters: `;`, `&&`, `||`, `|`, `` ` ``, `$`, `../` are not allowed.

Root Causes

Bug #1: KeyError - ‘transferStatus’

Location: backup/backupManager.py line 1253

Issue: The code attempts to access data['transferStatus'] without first checking if the key exists in the response. When the remote API returns an error response without this key, Python raises a KeyError which gets caught and displayed as 'transferStatus'.

Code Before Fix:

data = json.loads(r.text)

if data['transferStatus'] == 1:  # KeyError if 'transferStatus' doesn't exist

Bug #2: Newline Character in IP Address

Location: backup/backupManager.py line 1238

Issue: The machine IP address is read from /etc/cyberpanel/machineIP without stripping the trailing newline character (\n). When this IP (containing \n) is sent to the remote server’s API endpoint, the security middleware (CyberCP/secMiddleware.py line 196) rejects it because newline characters are blocked to prevent command injection attacks.

Code Before Fix:

ipFile = os.path.join("/etc", "cyberpanel", "machineIP")
f = open(ipFile)
ownIP = f.read()  # Contains '\n' at the end

Security Validation in secMiddleware.py:

if isinstance(value, (str, bytes)) and (value.find('\n') > -1 or value.find(';') > -1 or ...):
    return HttpResponse(json.dumps({
        'error_message': "API request contains potentially dangerous characters..."
    }))

Solution

Fix #1: Add Proper Error Handling

Add validation to check if transferStatus key exists before accessing it:

data = json.loads(r.text)

# Check if transferStatus key exists in response
if 'transferStatus' not in data:
    error_msg = data.get('error_message', 'Invalid response from remote server: ' + str(data))
    final_json = json.dumps({'remoteTransferStatus': 0,
                             'error_message': "Can not initiate remote transfer. Error message: " + error_msg})
    return HttpResponse(final_json)

if data['transferStatus'] == 1:
    # ... rest of the code

Also update the else block to safely get error_message:

else:
    error_msg = data.get('error_message', 'Unknown error from remote server')
    final_json = json.dumps({'remoteTransferStatus': 0,
                             'error_message': "Can not initiate remote transfer. Error message: " + error_msg})
    return HttpResponse(final_json)

Fix #2: Strip Newline from IP Address

Change line 1238 to strip whitespace characters:

ipFile = os.path.join("/etc", "cyberpanel", "machineIP")
f = open(ipFile)
ownIP = f.read().strip()  # Remove trailing newline and whitespace

Implementation Steps

Option 1: Manual Patch (Recommended)

  1. Backup the original file:

    sudo cp /usr/local/CyberCP/public/backup/backupManager.py /usr/local/CyberCP/public/backup/backupManager.py.backup
    
  2. Edit the file:

    sudo nano /usr/local/CyberCP/public/backup/backupManager.py
    
  3. Apply Fix #2 (around line 1238):

    Find:

    ownIP = f.read()
    

    Replace with:

    ownIP = f.read().strip()
    
  4. Apply Fix #1 (around line 1251-1253):

    Find:

    data = json.loads(r.text)
    
    if data['transferStatus'] == 1:
    

    Replace with:

    data = json.loads(r.text)
    
    # Check if transferStatus key exists in response
    if 'transferStatus' not in data:
        error_msg = data.get('error_message', 'Invalid response from remote server: ' + str(data))
        final_json = json.dumps({'remoteTransferStatus': 0,
                                 'error_message': "Can not initiate remote transfer. Error message: " + error_msg})
        return HttpResponse(final_json)
    
    if data['transferStatus'] == 1:
    
  5. Update the else block (around line 1278-1282):

    Find:

    else:
        final_json = json.dumps({'remoteTransferStatus': 0,
                                 'error_message': "Can not initiate remote transfer. Error message: " +
                                                  data['error_message']})
        return HttpResponse(final_json)
    

    Replace with:

    else:
        error_msg = data.get('error_message', 'Unknown error from remote server')
        final_json = json.dumps({'remoteTransferStatus': 0,
                                 'error_message': "Can not initiate remote transfer. Error message: " + error_msg})
        return HttpResponse(final_json)
    
  6. Restart CyberPanel services:

    sudo systemctl restart lscpd
    

Option 2: Replace the Modified File

  1. Download the fixed file to your server
  2. Replace the original:
    sudo cp backupManager.py /usr/local/CyberCP/public/backup/backupManager.py
    sudo systemctl restart lscpd
    

Verification

After applying the fix:

  1. Test the remote backup transfer:

    • Go to https://your-server-ip:8090/backup/remoteBackups
    • Enter remote server IP, admin password
    • Select a website
    • Click “Start Transfer”
  2. Check for proper error messages:

    • If there are connection issues, you should now see meaningful error messages instead of 'transferStatus'
    • The security validation error should no longer appear
  3. Enable debug mode (optional):

    sudo touch /usr/local/CyberCP/debug
    

    Then check logs at /usr/local/CyberCP/logs/ for detailed transfer status

Technical Details

Why This Bug Existed

  1. Inconsistent Code Pattern: Throughout the CyberPanel codebase, when reading from /etc/cyberpanel/machineIP, the standard pattern is:

    ipData = f.read()
    ipAddress = ipData.split('\n', 1)[0]
    

    The bug in backupManager.py was an inconsistency where this pattern wasn’t followed.

  2. Missing Validation: The code assumed the API would always return a valid response with transferStatus key, but didn’t handle cases where the API might return an error response with a different structure.

Files Modified

  • File: /usr/local/CyberCP/public/backup/backupManager.py
  • Function: BackupManager.starRemoteTransfer() (note: typo in original function name)
  • Lines Changed: 1238, 1253-1258, 1286-1289

Related Files (No Changes Needed)

  • CyberCP/secMiddleware.py - Security validation middleware
  • plogical/remoteBackup.py - Remote backup utilities
  • api/views.py - API endpoint for remoteTransfer

Additional Notes

Prerequisites for Remote Backup

Ensure both servers have:

  • :white_check_mark: Ports 8090 (CyberPanel) and SSH port (default 22) open
  • :white_check_mark: Admin user has API access enabled
  • :white_check_mark: SSH root login enabled (the code automatically enables this)
  • :white_check_mark: Valid SSL certificates for CyberPanel

Common Issues After Fix

If you still face issues after applying the fix:

  1. Check firewall rules:

    sudo firewall-cmd --list-all
    
  2. Verify API access:

    • Go to Users → List Users
    • Edit admin user
    • Ensure “API Access” is enabled
  3. Check SSH connectivity:

    ssh root@remote-server-ip
    
  4. Review logs:

    tail -f /usr/local/CyberCP/logs/access.log
    tail -f /usr/local/CyberCP/logs/error.log
    

Contributing

If you encounter any issues with this fix or have improvements, please report them to the CyberPanel GitHub repository:

Version Information

  • CyberPanel Version: Stable branch (as of 2025-10-22)
  • Affected Versions: All versions with remote backup feature
  • Fix Status: Pending official merge into stable branch

License

This fix follows the same license as CyberPanel (GPL-3.0)

Im getting Internal Error

The server encountered an unexpected condition which prevented it from fulfilling the request.strong text

Please explain in more detail what error you’re getting and where exactly it appears. A screenshot or the exact error message would help me understand the issue better

I did only change fix #2 on line 1238 and it is working now. Otherwhise I got a 500-error on the whole server. Thank you. Seems like Cyberpanel is full of these bugs. However have you got google drive backups working? I´m getting a “Scope has changed from “xxxx” to “xxxx xxxx xxxx”.” error when trying to connect my google account.

The error “Scope has changed from ‘xxxx’ to ‘xxxx xxxx xxxx’” occurs because scopes are being stored as a string but Google’s OAuth2 library expects them as a list.

Root Cause

Location 1:

backup/backupManager.py line 121

  • Scopes received from OAuth callback are stored as a string
  • Google expects a list of scopes

Location 2:

plogical/IncScheduler.py lines 262, 280, 372

  • When creating credentials, scopes need to be in list format
  • If stored as string, it causes scope validation errors

You got a fix for this aswell? :sweat_smile:

The Problem

When you try to connect Google Drive, you get:


Scope has changed from "xxxx" to "xxxx xxxx xxxx"

This happens because the code stores scopes like "scope1 scope2" (string) but Google needs ["scope1", "scope2"] (list).

The Fix

You need to modify two files:

File 1: /usr/local/CyberCP/backup/backupManager.py

Around line 121, change this:


gDriveData['scopes'] = request.GET.get('s')

To this:


scopes_string = request.GET.get('s')

if isinstance(scopes_string, str):

gDriveData['scopes'] = scopes_string.split()

else:

gDriveData['scopes'] = scopes_string if scopes_string else []

File 2: /usr/local/CyberCP/plogical/IncScheduler.py

Find all three places where google.oauth2.credentials.Credentials is created (around lines 259, 275, and 367).

Before each credential creation, add this scope conversion:


scopes = gDriveData.get('scopes', [])

if isinstance(scopes, str):

scopes = scopes.split() if scopes else []

elif not isinstance(scopes, list):

scopes = []

Then use scopes instead of gDriveData['scopes'] in the Credentials call.

How to Apply

  1. Backup the files first:

sudo cp /usr/local/CyberCP/backup/backupManager.py /usr/local/CyberCP/public/backup/backupManager.py.backup

sudo cp /usr/local/CyberCP/plogical/IncScheduler.py /usr/local/CyberCP/plogical/IncScheduler.py.backup

  1. Edit the files with nano or your preferred editor

  2. Restart CyberPanel:


sudo systemctl restart lscpd

  1. Delete your old Google Drive account in CyberPanel and revoke access at https:// myaccount. google. com/ permissions

  2. Set up a fresh Google Drive account - it should work now!

  3. here is working backup and incscheduler github . com /Dynamicearner/cyberpanelrelatedissues/tree/main

Note: The file locations mentioned are based on my configuration. Please edit them according to your own setup if needed.

:joy: yeah if this work for you then tell me by the way in my machine its working

I´ll try and get back to you! Getting Error message: [Errno 28] No space left on device [736][5009] on remote backups, is it maybe tmp? I have 160gb ssd and 8gig ram so it should be enough

This topic was automatically closed 3 hours after the last reply. New replies are no longer allowed.