Summary
barman-cloud-backup --cloud-provider azure-blob-storage --snapshot-instance ... fails immediately when run against a recent azure-mgmt-compute (38.0.0 verified) because barman passes the snapshot definition as a flat dict whose keys (incremental, creation_data) live in properties.* in the wire format. The SDK's strict deserializer rejects them at the root level.
Error
ERROR: Backup failed uploading data ((InvalidRequestContent) The request content was invalid
and could not be deserialized: 'Could not find member ''incremental'' on object of type
''ResourceDefinition''. Path 'incremental', line 1, position 45.'.)
Root cause
barman/cloud_providers/azure_blob_storage.py::_take_snapshot (current master too):
self.client.snapshots.begin_create_or_update(
resource_group, snapshot_name,
{
"location": location,
"incremental": True,
"creation_data": {"create_option": "Copy", "source_uri": disk_id},
},
)
azure-mgmt-compute's Snapshot._attribute_map:
| Python attribute |
wire key |
location |
location |
incremental |
properties.incremental |
creation_data |
properties.creationData |
So incremental and creation_data must live under properties on the wire. The flat dict barman sends is neither a Snapshot model instance nor wire-format JSON. Older azure-mgmt-compute releases accepted the flat shape leniently; 38.0.0 (and likely some earlier versions of the strict-deserializer track) reject it.
Reproduction
Environment:
- OS: Rocky Linux 9.6
- Python: 3.12.12
- PostgreSQL 16.9 / Patroni 4.0.5
- barman / barman-cli / barman-cloud-backup: 3.18.0 (PGDG)
- azure-core 1.41.0 / azure-identity 1.25.3 / azure-mgmt-core 1.6.0
- azure-mgmt-compute 38.0.0 / azure-storage-blob 12.29.0
VM is in Azure (koreacentral region), single managed data disk attached, user-assigned managed identity with Storage Blob Data Contributor on the destination storage account.
Command (sanitized):
AZURE_STORAGE_AUTH_MECHANISM=managed-identity barman-cloud-backup \
--cloud-provider azure-blob-storage \
-h localhost -p 5432 -U postgres \
--azure-subscription-id <sub-id> --azure-resource-group <rg> \
--azure-credential managed-identity \
--snapshot-instance <vm-name> --snapshot-disk <data-disk-name> \
--name <backup-name> \
https://<storage>.blob.core.windows.net/<container> <server-name>
The cli authenticates fine and reaches _take_snapshot before the failure surfaces.
Workaround
Pinning azure-mgmt-compute below the strict-deserializer release unblocks the backup:
pip install --user 'azure-mgmt-compute>=37.1.0,<38.0.0'
Verified: azure-mgmt-compute==37.2.0 runs the identical barman-cloud-backup command to a successful snapshot.
Suggested fix
Pass a Snapshot model object (or wire-format dict) instead of the flat dict:
from azure.mgmt.compute.models import Snapshot, CreationData, DiskCreateOption
self.client.snapshots.begin_create_or_update(
resource_group,
snapshot_name,
Snapshot(
location=location,
incremental=True,
creation_data=CreationData(
create_option=DiskCreateOption.COPY,
source_uri=disk_id,
),
),
)
This is unambiguous regardless of the SDK's deserializer mode.
In addition, the azure-snapshots extra in setup.py (line 55) has no upper bound:
"azure-snapshots": ["azure-identity", "azure-mgmt-compute"],
Consider adding azure-mgmt-compute<38.0.0 as a short-term safety pin (or, once the model-object fix above lands, a documented lower bound) so a fresh pip install doesn't auto-pick a version that breaks the snapshot path.
Affected versions
Confirmed on barman 3.18.0. master (as of 2026-05-17) still uses the same flat-dict pattern; no fix appears to be present yet.
References
Happy to send a PR if this analysis matches your intent for the fix shape — cc @didorgas @martinmarques.
Summary
barman-cloud-backup --cloud-provider azure-blob-storage --snapshot-instance ...fails immediately when run against a recentazure-mgmt-compute(38.0.0 verified) because barman passes the snapshot definition as a flat dict whose keys (incremental,creation_data) live inproperties.*in the wire format. The SDK's strict deserializer rejects them at the root level.Error
Root cause
barman/cloud_providers/azure_blob_storage.py::_take_snapshot(currentmastertoo):azure-mgmt-compute'sSnapshot._attribute_map:locationlocationincrementalproperties.incrementalcreation_dataproperties.creationDataSo
incrementalandcreation_datamust live underpropertieson the wire. The flat dict barman sends is neither aSnapshotmodel instance nor wire-format JSON. Older azure-mgmt-compute releases accepted the flat shape leniently; 38.0.0 (and likely some earlier versions of the strict-deserializer track) reject it.Reproduction
Environment:
VM is in Azure (koreacentral region), single managed data disk attached, user-assigned managed identity with Storage Blob Data Contributor on the destination storage account.
Command (sanitized):
The cli authenticates fine and reaches
_take_snapshotbefore the failure surfaces.Workaround
Pinning
azure-mgmt-computebelow the strict-deserializer release unblocks the backup:Verified:
azure-mgmt-compute==37.2.0runs the identicalbarman-cloud-backupcommand to a successful snapshot.Suggested fix
Pass a
Snapshotmodel object (or wire-format dict) instead of the flat dict:This is unambiguous regardless of the SDK's deserializer mode.
In addition, the
azure-snapshotsextra insetup.py(line 55) has no upper bound:Consider adding
azure-mgmt-compute<38.0.0as a short-term safety pin (or, once the model-object fix above lands, a documented lower bound) so a freshpip installdoesn't auto-pick a version that breaks the snapshot path.Affected versions
Confirmed on barman 3.18.0.
master(as of 2026-05-17) still uses the same flat-dict pattern; no fix appears to be present yet.References
Microsoft.Compute/snapshotsREST API: https://learn.microsoft.com/en-us/rest/api/compute/snapshots/create-or-update?view=rest-compute-2025-04-01SnapshotPython model: https://learn.microsoft.com/en-us/python/api/azure-mgmt-compute/azure.mgmt.compute.models.snapshotHappy to send a PR if this analysis matches your intent for the fix shape — cc @didorgas @martinmarques.