Hi everyone,
MultiPortal 1.2.3 is a patch release that resolves issues identified after the 1.2.2 release. It stops tenants reaching each other’s ISO images, closes an open redirect in legacy SAML sign-in, and hardens the virtual machine console and its Node.js proxy in line with the October 2026 Node.js security releases.
It also fixes white-label branding on installations with more than one application node, duplicate backup records, cloning into HA-enabled data centres and from Windows templates, virtual machine import on LINSTOR/DRBD storage, and VM ID allocation on busy clusters. The networking API now identifies everything by UUID, which is a breaking change for integrations (see Upgrade Notes).
We recommend upgrading at the next available maintenance window for all environments, and particularly for those that let tenants upload ISO images, run more than one application node behind a load balancer, or use legacy SAML sign-in.
Security and Access
- Tenants are kept to their own ISO images. A tenant who had the link to another tenant’s ISO image could edit or delete it, including the file on Proxmox, and could delete a shared ISO. A tenant now sees its own, shared and public ISO images, as the list shows them, and can change only its own. A reseller works through its tenants, and any other request is answered as not found, so the existence of another tenant’s ISO is not confirmed. Editing an ISO changes only its name and description.
- Legacy SAML sign-in returns only to this site. The return address carried through a legacy SAML sign-in was followed as given, so a crafted sign-in link could send a signed-in user on to another website. An address on another host, scheme or port, or one that cannot be read, now goes to the home page instead.
- Virtual machine creation is limited to the user’s own VDCs. Creating a virtual machine, in the portal and through the API, now checks that the target virtual data centre belongs to the user’s own company. Custom roles can also only be granted the permissions the role editor offers; anything else in the request is discarded and logged.
- Virtual machine hardware shows only its own data centre’s networks. When two data centres used the same Proxmox VNet ID, a virtual machine’s Hardware tab could show the name of another tenant’s network. Network names are now looked up within the virtual machine’s own data centre.
- Virtual machine console hardened. A console link can no longer point the browser’s console connection at another server; the console always connects to the page’s own address, so custom domains work as before. The console service no longer writes the Proxmox login ticket to its log, its shared API key is compared in constant time, and each use of the console credentials endpoint is recorded in the virtual machine log, without credentials. Console session records, which hold short-lived console credentials, are now deleted after five minutes. Unused legacy console code has been removed.
- Console proxy protected against the October 2026 Node.js advisories. The console proxy (
multiportal-websocket) no longer accepts Brotli-compressed responses, so the Node.js Brotli decoder flaw (CVE-2026-111497) cannot be reached on any Node.js version. The proxy logs a start-up warning on an end-of-life Node.js (18 or 20), and its redirect library has been updated to a release that no longer leaks credential headers across origins. Node.js 22 LTS is recommended (see Upgrade Notes). - Uploaded files can no longer be run as scripts. The Caddy configuration now refuses PHP and other script files under
/uploads. Existing installations need a one-line configuration change (see Upgrade Notes). - Dependency update.
symfony/yamlhas been updated to 7.4.21 to address CVE-2026-109413.
Reliability and Performance
- White-label branding works on every application node. Logos, favicons and login backgrounds were saved to the disk of whichever node handled the upload, so behind a load balancer they disappeared intermittently. Branding images are now stored in the database and served from every node. Existing images are moved across during the upgrade.
- The white-label logo now appears on the two-factor sign-in page. Logos set by URL were shown on the login page but not on the two-factor verification page.
- Backup sync no longer creates duplicate backup records. Two scheduled tasks could each register the same backup archive, so one backup appeared twice and was counted twice in backup storage usage. Each archive is now recorded once, existing duplicates are removed during the upgrade, and backup storage usage counts each archive once.
- ISO images are no longer marked Failed when Proxmox cannot be reached. A timeout, an offline node or an expired token used to mark a healthy ISO image as Failed, and nothing set it back. An ISO image is now marked Failed only when Proxmox confirms the file is gone, and a Failed ISO that Proxmox lists again is restored. While a data centre is unreachable, the ISO page no longer hangs; it shows the status as Unknown and names the data centres it could not reach.
- ISO images with long file names upload successfully. An upload with a very long file name reached 100% and then vanished. It now completes and appears in the list, under its original display name.
- Cloning into an HA-enabled data centre no longer leaves the virtual machine in an HA error state. The clone was registered with Proxmox HA while it was still copying, which pinned it to the source node and left it unable to start. HA is now applied once the clone has finished. If the clone is still copying when the wait ends, the virtual machine is kept, HA is not applied, and the clone wizard says why. A clone is also placed on a node allowed by its node-affinity rule.
- New virtual machines avoid nodes in HA maintenance. Creating, cloning and restoring a virtual machine, and uploading an ISO image, no longer pick a Proxmox node that HA has placed in maintenance.
- VM creation no longer fails with “Unable to generate unique Proxmox VM ID after 100 attempts”. On a busy cluster, a record left behind by a machine deleted directly in Proxmox, or more than 100 machines above the “begin VM IDs at” setting, could stop every create, clone and restore. The new machine now gets the next free ID, the old record’s ID is never reused, and container IDs are no longer handed to virtual machines. If Proxmox cannot be read, creation stops with a message saying so rather than guessing an ID. A retried create now carries the right name in Proxmox and gives up after five attempts. A new read-only command,
php yii vm-orphan/stale-records, lists records whose virtual machine is no longer on the cluster. - Divided bandwidth is shared correctly when a virtual machine is added. In a virtual data centre using Divided bandwidth, adding a virtual machine left the existing machines on their old, larger limit, so the pool was over-committed. Every network card’s limit is now updated.
- Clone node lookup restored. A background lookup that confirms which node a cloned virtual machine landed on failed on every call and filled the post-task log with errors. It now works.
Bug Fixes
- Clones from Windows (Cloudbase-Init) templates get a network card. Cloning a template without cloud-init hid the whole network section, so the virtual machine was created with no network card. The network section is now always shown; only the in-guest IP settings are hidden for templates without cloud-init. New virtual machines created from an ISO now have their network card connected by default.
- Deploy from Template no longer shows cloud-init errors for templates without cloud-init. Hidden cloud-init fields, for example ones filled by a password manager, were still submitted and validated. They are now ignored for templates without cloud-init.
- Deploy from Template opens on VDCs that already contain virtual machines. The wizard failed with “Error loading content” when the resources already in use could not be totalled. It now opens.
- Custom tenant roles can create virtual machines. A custom tenant role holding the Virtual Machine Admin permission got “Error loading content” from New Virtual Machine unless the user was also a Tenant Administrator.
- Editing an internal network opens the right network. Internal networks could be issued a VNet ID already in use, so editing one could open a different network, and a reseller got a blank “Error loading content” dialog. New IDs are now unique within each data centre. Dialogs that are refused now show the reason, such as “Access denied” or “Not found”, instead of a blank error.
- Internal networks can be created on a second Proxmox cluster. Creation failed with “Zone ID already exists” when the zone ID was already used in the data centre. A repair command for zone records already duplicated is described in the Upgrade Notes.
- VM Import recognises disks on LINSTOR/DRBD storage. The VM Import wizard reported “has no storage configured” for virtual machines on LINSTOR/DRBD storage, whose volumes are named differently. Disks are now recognised by the slot they are attached to. A template on such storage now reports its real size, so clones from it are checked against the virtual data centre’s free storage. A disk written as
size=1Tis read at its real size, and a storage defined once per node, such aslocal, is accepted when any node’s entry is on one of the virtual data centre’s storage policies. EFI and TPM state volumes are no longer counted as disks. - Editing virtual machine hardware no longer fails with “Capacity cannot be downgraded”. A disk whose size is not a whole number of mebibytes, which is usual on LINSTOR/DRBD storage, was shown rounded, and saving any other change refused the whole edit. Disk sizes are now compared in whole bytes, in the portal and the API, so an unchanged disk is left alone.
- Backup Job virtual machine picker no longer selects two machines on a double-click.
- Backup protection can be changed on a backup with no virtual machine. A backup that is no longer associated with a virtual machine can now have its protection enabled or disabled.
- Disabled form fields look disabled in light mode. Fields switched off, such as the retention fields when “Keep all backups” is ticked, looked the same as editable fields.
- Scheduled backup schedules are translated. The weekly day picker, time field and schedule summary now follow the selected language.
- The Upload ISO wizard’s Public option is saved. A Service Provider’s public upload was saved as private.
API and Integrations
- Breaking change: the networking API uses UUIDs only. The v1 networking endpoints identified data centres, virtual data centres, tenants and networks by internal integer IDs that the API never exposed. They now accept and return UUIDs only, and an integer value is rejected with HTTP 422 (see Upgrade Notes).
- Attaching and detaching networks through the API.
DELETE /virtual-machine/{id}/network/{device}returned a server error while Proxmox still removed the network card, so the API and the portal kept listing it; it now succeeds and both update straight away. The response to attaching a network now says a network was added, not storage. - Virtual machine creation is scoped to the caller’s own VDCs.
POST /virtual-machinenow refuses a virtual data centre that belongs to another company. - Hardware updates compare disk sizes in whole bytes. The API’s hardware update no longer refuses an unchanged disk whose size is not a whole number of mebibytes. A size that is not a plain number is refused with “Capacity is not a valid size.”
Upgrade Notes
- This patch release includes database migrations. Please take a backup of your database prior to upgrading; the migrations run as part of the standard upgrade procedure.
- Breaking API change: networking endpoints are UUID-only. Replace any integer
data_center_id,tenant_idorvirtual_data_center_idsvalue, and any integer network ID in a URL, with the UUID fromGET /api/v1/data-center,GET /api/v1/virtual-data-centerorGET /api/v1/tenant. Reseller networking endpoints are UUID-only for tenants, data centres and VDCs as well. Existing networks are given a UUID during the upgrade. - Duplicate VNet IDs within one data centre stop the upgrade. The upgrade adds a unique index on internal-network VNet IDs per data centre. Two data centres sharing an ID is expected and allowed. If one data centre holds the same ID twice, the migration stops with a message listing the duplicates and the query that finds them; reconcile them and run the upgrade again.
- Duplicate backup records are removed. The upgrade keeps the oldest record for each backup archive and removes the rest. Backup storage usage figures may fall to the true value.
- Branding images move into the database. The upgrade copies each logo, favicon and login background from disk into the database. On an installation with more than one application node, an image that sits only on another node’s disk is left as it was; check branding after the upgrade and upload again any image that does not appear.
- Block scripts under
/uploadsin Caddy. New installations get this automatically. On an existing installation, add the following to the(backend_common)snippet, and to the main site block if it does not import that snippet, then reload Caddy.
@uploads_scripts path_regexp ^/uploads/.*\.(php|php5|php7|phtml|phar)$
handle @uploads_scripts {
respond 403
}
- Node.js 22 LTS recommended for the console proxy. Upgrading to 1.2.3 does not require a new Node.js, and Node.js 18 and 20 keep working with a start-up warning. To move to Node.js 22, install it from NodeSource (
https://deb.nodesource.com/setup_22.x), then runsudo systemctl restart multiportal-websocket. Do not use nvm or a per-user Node.js; the service does not see it. - Proxmox API token privileges. VM ID allocation now reads every guest on the cluster. MultiPortal’s Proxmox API token needs
VM.Auditon every guest; without it, creation can stop with a message that Proxmox could not be read. - Repair duplicated network zones. If internal-network creation failed with “Zone ID already exists”, run
php yii zone-dedupe/proxmox-idsto preview the repair, then again with--commit=1to apply it. The shared zone on Proxmox is not changed. - Find records for virtual machines deleted in Proxmox.
php yii vm-orphan/stale-recordslists them and says what is safe to do with each. It changes nothing. - Clones from LINSTOR/DRBD templates are checked against quota. Such templates used to report a size of zero, so their clones were never checked against free storage. A clone that went through over quota before is now refused.
Thanks
Thanks to everyone who reported the issues that went into 1.2.3, especially the support tickets that pinned down the LINSTOR/DRBD import and VM ID allocation problems. If you have already upgraded, let us know how it went, and questions or anything odd are welcome in the usual categories.