Introduction
A backup migration can bring the new repository online while protected servers still write backups to the old target. Jobs appear successful, but restore points land in the retired system, retention behaves inconsistently, or one protection group uses the new repository while another still depends on the previous backup environment because agents, policies, or repository mappings were not fully updated.
This scenario is common when migrating between backup platforms (e.g., Veeam to Commvault, Veritas NetBackup to Rubrik), moving backup storage to new object storage or SAN, or consolidating backup infrastructure across data centers. The new backup server may be fully configured with all policies imported, but agents continue writing to the old repository until their configuration is updated.
Treat this as a backup-destination problem instead of a generic restore or storage outage. Start by checking where an affected backup agent actually sends its job data, because migrations often stand up new backup infrastructure first while endpoints continue using their old repository assignment.
Symptoms
- Backup jobs still write to the old repository after migration
- New backup infrastructure is online, but fresh restore points do not appear there
- One server or policy uses the new repository while another still targets the previous backup system
- Retention, immutability, or offsite copy behavior differs after the cutover
- Backups appear healthy until the old repository is decommissioned
- The issue started after moving backup software, repositories, object storage, or protection policies
- Backup console shows successful jobs but storage consumption grows on old repository
- New restore points are not visible in the new backup catalog
- Backup job logs show data being written to old storage endpoints
- Capacity alerts on old storage despite migration being "complete"
Common Causes
- The backup agent or proxy still has the old repository, vault, or storage target assigned
- A backup policy, protection group, or job template still maps workloads to the previous repository
- One backup server or media proxy was migrated while another still manages jobs through the retired platform
- Credentials, repository IDs, or object storage endpoints still resolve to the old backup target
- Agents cached the previous server assignment and never re-registered with the new backup environment
- Validation confirmed the new repository existed but did not verify where live backup jobs actually wrote data
- Backup configuration was imported but repository references were not updated
- Multiple backup policies with conflicting repository assignments
- Load balancer or DNS still routing backup traffic to old infrastructure
- Agent installation packages in deployment systems still point to old backup server
Step-by-Step Fix
Step 1: Identify Active Backup Destination
Capture one affected backup job and record the exact repository, media server, or storage endpoint it uses. The runtime destination matters more than the migration checklist.
For Veeam Backup & Replication: ```powershell # Connect to Veeam Backup Server Connect-VBRServer -Server veeam-new.company.com
# Check backup repositories Get-VBRBackupRepository | Select-Object Name, Path, Host, Status
# Check which repository a backup job uses Get-VBRJob | Select-Object Name, @{N='Repository';E={$_.FindParentRepository().Name}}, @{N='TargetPath';E={$_.FindParentRepository().Path}}
# Check recent backup sessions and their storage Get-VBRBackupSession | Sort-Object CreationTime -Descending | Select-Object -First 10 Name, Result, BackupSizeGB ```
For Commvault: ```bash # Check storage library assignments qinst -li
# Check backup destinations for a specific subclient qscript -cs 1 -s GetSubclientProperties -arg subclientId
# List recent job details including storage qjob -j -all -disp -st Completed | head -50 ```
For generic backup agent configuration: ```powershell # Windows - check backup agent config files Get-ChildItem -Path "C:\Program Files" -Recurse -Filter "*backup*.conf" -ErrorAction SilentlyContinue | ForEach-Object { Write-Host "Config file: $($_.FullName)" Get-Content $_.FullName | Select-String -Pattern "server|repository|target|storage" }
# Check registry for backup agent settings Get-ChildItem "HKLM:\SOFTWARE" -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "backup|agent" } | Get-ItemProperty | Select-Object PSPath, Server, Repository, TargetServer ```
Step 2: Compare with Expected Post-Migration Design
Compare that active target with the intended post-migration backup design. One stale repository mapping can keep protected systems tied to the retired platform.
Expected configuration (new repository):
``
Repository: Backup-Repo-New
Storage Path: /mnt/new-backup-storage/veeam
Object Storage: s3://backup-bucket-new.company.com
Media Server: backup-proxy-new.company.com
Problematic configuration (old repository):
``
Repository: Backup-Repo-Old <-- OLD
Storage Path: /mnt/old-backup-storage/veeam <-- OLD
Object Storage: s3://backup-bucket-old.company.com <-- OLD
Media Server: backup-proxy-old.company.com <-- OLD
Step 3: Review All Backup Configuration Layers
Review backup policies, protection groups, repository assignments, proxy settings, and agent registration state for references to the old environment. Backup routing often spans several control layers.
Check backup policies and protection groups: ```powershell # Veeam - list all job configurations Get-VBRJob | ForEach-Object { [PSCustomObject]@{ JobName = $_.Name Repository = $_.FindParentRepository().Name RepositoryPath = $_.FindParentRepository().Path Proxy = ($_.FindChildProxies() | Select-Object -ExpandProperty Name) -join "," } } | Format-Table -AutoSize
# Check for old repository references Get-VBRBackupRepository | Where-Object { $_.Path -like "*old*" -or $_.Name -like "*old*" } ```
Check agent registration: ```powershell # Check which backup server agents are registered with Get-ChildItem "HKLM:\SOFTWARE[BackupVendor]" | Get-ItemProperty | Select-Object Server, Port, RegistrationKey
# Check agent service configuration Get-Service | Where-Object { $_.Name -like "*backup*" -or $_.Name -like "*agent*" } | Select-Object Name, Status sc.exe query "[BackupAgentService]" ```
Check deployment system for old packages:
``powershell
# SCCM - check backup agent package source
Get-CMPackage | Where-Object { $_.Name -like "*backup*" } | Select-Object Name, PackageSourcePath
Step 4: Check Different Job Types Separately
Check whether different job types such as full, incremental, archive, or replication backups use different targets. Migrations often move one path while another stays behind.
powershell
# Veeam - check different job types
Get-VBRJob | Group-Object JobType | ForEach-Object {
Write-Host "nJob Type: $($_.Name)"
$_.Group | Select-Object Name, @{N='Repository';E={$_.FindParentRepository().Name}}
}
# Check backup copy jobs separately (often have different targets) Get-VBRJob -Type BackupCopy | Select-Object Name, @{N='Repository';E={$_.FindParentRepository().Name}} ```
Step 5: Update Repository Assignments
Update the authoritative repository or policy mapping and re-register or restart affected agents if required. Job runners can keep using cached targets until they reload configuration.
Veeam example - update job repository: ```powershell # Get the new repository $newRepo = Get-VBRBackupRepository -Name "Backup-Repo-New"
# Update jobs to use new repository Get-VBRJob | Where-Object { $_.FindParentRepository().Name -like "*old*" } | ForEach-Object { Write-Host "Updating job: $($_.Name)" Set-VBRJobRepository -Job $_ -Repository $newRepo }
# Restart backup proxy services to pick up new config Get-VBRProxy | ForEach-Object { Invoke-Command -ComputerName $_.Host.Name -ScriptBlock { Restart-Service "VeeamTransportSvc" } } ```
Generic agent re-registration: ```powershell # Uninstall old agent and install new one pointing to correct server # Example for generic backup agent
# 1. Get current agent config $agentConfig = Get-ItemProperty "HKLM:\SOFTWARE[BackupVendor]"
# 2. Update configuration Set-ItemProperty "HKLM:\SOFTWARE[BackupVendor]" -Name "Server" -Value "backup-new.company.com" Set-ItemProperty "HKLM:\SOFTWARE[BackupVendor]" -Name "Repository" -Value "New-Repository"
# 3. Restart agent service Restart-Service "[BackupAgentService]"
# 4. Or re-register with new server & "C:\Program Files[BackupVendor]\register.exe" -server backup-new.company.com -key "NEW-REGISTRATION-KEY" ```
Step 6: Verify Backup Writes to New Repository
Trigger a controlled backup and confirm the new restore point appears in the intended repository. A successful job status alone does not prove the backup landed in the right place.
```powershell # Run an ad-hoc backup $job = Get-VBRJob -Name "Test-VM-Backup" Start-VBRJob -Job $job -Reason "Migration validation"
# Wait for completion and check restore point location $backup = Get-VBRBackup -Name "Test-VM-Backup" $latestRp = $backup.GetStorages() | Sort-Object CreationTime -Descending | Select-Object -First 1 Write-Host "Latest restore point: $($latestRp.FilePath)" Write-Host "Repository: $($backup.Repository.Name)" Write-Host "Creation time: $($latestRp.CreationTime)" ```
Verify storage growth on new repository: ```powershell # Check storage before and after backup $before = Get-VBRBackupRepository -Name "Backup-Repo-New" Write-Host "Used space before: $([math]::Round($before.Info.CapacityUsedGB, 2)) GB"
# Run backup...
$after = Get-VBRBackupRepository -Name "Backup-Repo-New" Write-Host "Used space after: $([math]::Round($after.Info.CapacityUsedGB, 2)) GB" ```
Step 7: Verify Old Repository Has No New Writes
Verify the old repository no longer receives writes from migrated systems. Mixed backup destinations can stay hidden until retention or restore is needed.
```powershell # Check old repository for recent writes $oldRepo = Get-VBRBackupRepository -Name "Backup-Repo-Old" $recentBackups = Get-VBRBackup | Where-Object { $_.RepositoryId -eq $oldRepo.Id }
$recentBackups | ForEach-Object { $backup = $_ $latestRp = $backup.GetStorages() | Sort-Object CreationTime -Descending | Select-Object -First 1 [PSCustomObject]@{ BackupName = $backup.Name LatestRestorePoint = $latestRp.CreationTime Age = (Get-Date) - $latestRp.CreationTime } } | Where-Object { $_.Age.TotalDays -lt 7 } | Format-Table
# If any backups have restore points less than 7 days old, still writing to old repo ```
Check object storage for new uploads: ```bash # AWS S3 example - check for recent uploads to old bucket aws s3 ls s3://backup-bucket-old/ --recursive | tail -50
# Check bucket size over time aws cloudwatch get-metric-statistics \ --namespace AWS/S3 \ --metric-name BucketSizeBytes \ --dimensions name=BucketName,value=backup-bucket-old \ --start-time $(date -d '7 days ago' -Iseconds) \ --end-time $(date -Iseconds) \ --period 86400 \ --statistics Average ```
Step 8: Handle Edge Cases
Review restore jobs, copy jobs, and retention policies if behavior still looks inconsistent. Secondary backup workflows often keep separate destination settings.
```powershell # Check backup copy jobs Get-VBRJob -Type BackupCopy | Select-Object Name, @{N='Repository';E={$_.FindParentRepository().Name}}, IsEnabled
# Check archive jobs Get-VBRJob | Where-Object { $_.JobType -eq "Archive" } | Select-Object Name, @{N='Repository';E={$_.FindParentRepository().Name}}
# Check tape jobs if applicable Get-VBRJob -Type TapeBackup | Select-Object Name, MediaPool, IsEnabled
# Check SOBR (Scale-Out Backup Repository) extent assignments Get-VBRScaleOutBackupRepository | ForEach-Object { Write-Host "SOBR: $($_.Name)" $_.Extents | Select-Object Repository, IsEnabled } ```
Verification
Confirm the fix by verifying:
- 1.Repository assignment check: All backup jobs point to new repository
- 2.```powershell
- 3.Get-VBRJob | Select-Object Name, @{N='Repository';E={$_.FindParentRepository().Name}} | Where-Object { $_.Repository -like "*old*" }
- 4.# Should return empty
- 5.
` - 6.Test backup and restore: Create a test backup and verify restore works from new repository
- 7.Storage monitoring: New repository shows growth, old repository shows no growth
- 8.Agent registration: All agents show new backup server in configuration
- 9.Job logs: Recent job logs show writes to new storage endpoints only
Prevention
To prevent this issue in future backup migrations:
- 1.Inventory all backup configurations before migration:
- 2.```powershell
- 3.# Export current configuration
- 4.Get-VBRJob | Select-Object Name, JobType, @{N='Repository';E={$_.FindParentRepository().Name}}, @{N='RepositoryPath';E={$_.FindParentRepository().Path}} | Export-Csv backup-config-pre-migration.csv
- 5.
` - 6.Use backup policy templates that can be updated centrally and inherited by all jobs.
- 7.Implement storage monitoring that alerts on unexpected writes to old repositories:
- 8.```powershell
- 9.# Monitor for writes to old repository
- 10.$schedule = New-JobTrigger -Daily -At 6am
- 11.$action = @{
- 12.Repository = "Backup-Repo-Old"
- 13.AlertThreshold = "1GB" # Alert if more than 1GB written in 24 hours
- 14.}
- 15.Register-ScheduledJob -Name "MonitorOldBackupRepo" -Trigger $schedule -ScriptBlock {
- 16.$oldRepo = Get-VBRBackupRepository -Name "Backup-Repo-Old"
- 17.$currentUsed = $oldRepo.Info.CapacityUsedGB
- 18.# Compare with yesterday's value and alert if increased
- 19.}
- 20.
` - 21.Validate migration with test restores before decommissioning old infrastructure.
- 22.Document ownership: Specify which team owns backup policies, agent deployment, and repository configuration.
- 23.Use phased migration: Move one protection group at a time, verify complete operation, then proceed.
- 24.Update deployment packages in SCCM/Intune to point to new backup server before migration starts.
- 25.Keep old repository read-only during migration transition to catch any straggler writes.
Related Articles
- [WordPress troubleshooting: Fix CloudFormation Permission Denied - C](fix-cloudformation-permission-denied)
- [Technical troubleshooting: Fix Cloud Migration Data Transfer Incomplete Issue](cloud-migration-data-transfer-incomplete)
- [Fix Database Migration Schema Lock Timeout in Infrastructure Migration](database-migration-schema-lock-timeout)
- [Fix DNS Cutover Propagation Delay Issue in Infrastructure Migration](dns-cutover-propagation-delay)
- [How to Fix Ansible Automation Controller Still Running Jobs Against the Old Execution Environment After Migration](fix-ansible-automation-controller-still-running-jobs-against-old-execution-environment-after-migration)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "How to Fix a Backup Agent Still Writing to the Old Repository After Migration", "description": "Troubleshoot backup migration issues by checking agent targets, repository mappings, backup policies, and stale protection settings.", "url": "https://www.fixwikihub.com/fix-backup-agent-still-writing-to-old-repository-after-migration", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-01T15:12:11.942Z", "dateModified": "2025-11-01T15:12:11.942Z" } </script>