Skip to content

revertSnapshot fails with an NPE when the snapshot's volume has been deleted #14644

Open

Description

@bhouse-nexthop

problem

revertSnapshot fails with a NullPointerException when the snapshot's volume has been deleted:

Cannot invoke "com.cloud.storage.VolumeVO.getState()" because "volume" is null
    at com.cloud.storage.snapshot.SnapshotManagerImpl.revertSnapshot

SnapshotManagerImpl.revertSnapshot looks the volume up with findById(), which does not return removed volumes, and uses the result without a null check. Volume snapshots outlive their volume, so any snapshot of a deleted volume hits this. The caller gets an internal error instead of being told why the snapshot cannot be reverted.

A few other snapshot APIs have the same gap:

  • copySnapshot without sourcezoneid takes the source zone from the volume, also looked up with findById(). For a snapshot of a deleted volume it fails with Cannot invoke "com.cloud.storage.Volume.getDataCenterId()" because "volume" is null. The copy itself does not need the volume, and the same copy works when sourcezoneid is passed.
  • createVolume from a snapshot and createTemplate from a snapshot look the volume up including removed rows, so a deleted volume is fine. They still NPE when the volume row itself is gone (parentVolume.getPassphraseId() in VolumeApiServiceImpl.allocVolume; for createTemplate, the template record is created and the job then fails in TemplateManagerImpl.createPrivateTemplate). A missing row is the case in listSnapshots fails with NPE in snapshot strategy canHandle when a snapshot's volume row no longer exists #14599.

versions

4.22, and main.

The steps to reproduce the bug

  1. Create a data volume, attach it to a VM, and take a volume snapshot of it.
  2. Detach and delete the volume. The snapshot remains.
  3. Call revertSnapshot id=<snapshot>. It fails with the NPE above.
  4. Call copySnapshot id=<snapshot> destzoneids=<another zone> without sourcezoneid. It fails with the getDataCenterId() NPE.

For createVolume snapshotid= and createTemplate snapshotid=, the volume row has to be missing from the volumes table.

What to do about it?

  • revertSnapshot: refuse with a clear error when the snapshot's volume no longer exists.
  • copySnapshot: when the volume is gone, take the source zone from the snapshot, which records the zone it was taken in.
  • createVolume and createTemplate from a snapshot: refuse with a clear error when the volume row is missing, instead of failing with an NPE.

Activity

  1. added 2 commits that reference this issue on Nov 9, 2026
    798f923
    9a11073
  2. added this to the 4.22.3 milestone on Nov 11, 2026
  3. github-actions commented on Nov 11, 2026

    @github-actions

    Warning

    threat detection engine error
    The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.

    What happened

    The threat detection engine failed to produce results.

    Review the workflow run logs for details.

    🎯 Triage report

    revertSnapshot fails with an NPE when the snapshot's volume has been deleted. SnapshotManagerImpl.revertSnapshot looks the volume up with findById(), which excludes removed rows, and then uses the result without a null check. The reporter also found that copySnapshot without sourcezoneid hits the same NPE, and that createVolume and createTemplate from a snapshot NPE when the volume row is missing entirely. The proposed fixes are a clear error for revert and create, and taking the source zone from the snapshot for copy.

    📊 Assessment

    Dimension Value Reasoning
    Type type:bug NPE in several snapshot APIs, with reproduction steps
    Component component:snapshot Failure is in snapshot manager lookups
    Severity Severity:Minor Only snapshots of deleted volumes; the API returns an internal error but no data is lost
    Labels type:bug, component:snapshot, Severity:Minor
    Coding agent Suitable Each API has a specified fix (clear error, or zone from snapshot)

    🔗 Similar issues

    💡 Notes and suggestions
    • Reproduction: create a volume, take a snapshot, delete the volume, then call revertSnapshot and copySnapshot without sourcezoneid.
    • createVolume and createTemplate from a snapshot only fail when the volume row is gone, which is a different case from a removed volume. Check both.

    Generated by Daily Issue Triage · copilot · haiku55 · ~6 AIC · ⊞ 3.8K · ◷

    Add this agentic workflow to your repo

    To install this agentic workflow, run

    gh aw add githubnext/agentics/workflows/daily-issue-triage.md@139fa09ef17cde4135e696ff8e7af09bc5ddfa6e
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions