hashicorp/packer · error

Failed cleaning up prior artifact: %s; pp is %s

Error message

Failed cleaning up prior artifact: %s; pp is %s

What it means

After a post-processor produces an artifact and the keep/discard decision says not to keep it, Run calls priorArtifact.Destroy() to clean it up. If Destroy fails, Run records "Failed cleaning up prior artifact: %s; pp is %s" — the first %s is the destroy error and the second is the post-processor type whose artifact could not be deleted. The build's error list accumulates this but the chain continues.

Source

Thrown at packer/build.go:447

				// This is the first post-processor. We handle deleting
				// previous artifacts a bit different because multiple
				// post-processors may be using the original and need it.
				if !keepOriginalArtifact && keep {
					log.Printf(
						"Flagging to keep original artifact from post-processor '%s'",
						corePP.PType)
					keepOriginalArtifact = true
				}
			} else {
				// We have a prior artifact. If we want to keep it, we append
				// it to the results list. Otherwise, we destroy it.
				if keep {
					artifacts = append(artifacts, priorArtifact)
				} else {
					log.Printf("Deleting prior artifact from post-processor '%s'", corePP.PType)
					if err := priorArtifact.Destroy(); err != nil {
						log.Printf("Error is %#v", err)
						errors = append(errors, fmt.Errorf("Failed cleaning up prior artifact: %s; pp is %s", err, corePP.PType))
					}
				}
			}

			priorArtifact = artifact
		}

		// Add on the last artifact to the results
		if priorArtifact != nil {
			artifacts = append(artifacts, priorArtifact)
		}
	}

	if keepOriginalArtifact {
		artifacts = append(artifacts, nil)
		copy(artifacts[1:], artifacts)
		artifacts[0] = builderArtifact
	} else {

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Check the destroy error text and the named post-processor type for the failing resource
  2. Verify credentials/permissions include delete rights for the artifact's backing resource (bucket, AMI, box)
  3. Manually delete the orphaned artifact, then fix keep/discard config (keep_input_artifact, except rules) to prevent recreation of unwanted artifacts
  4. Re-run with PACKER_LOG=1 to see the Destroy error details logged via log.Printf("Error is %#v")

Example fix

// before
post-processors {
  post-processor "checksum" { }  // discarded artifact cleanup failing
}
// after - keep artifacts intentionally so cleanup is skipped, delete manually
post-processors {
  post-processor "checksum" { keep_input_artifact = true }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure credentials can delete resources before discarding artifacts:
// e.g. for S3 artifacts, verify s3:DeleteObject; for AMIs, ec2:DeregisterImage.

Try / catch

artifacts, err := build.Run(ctx, ui)
if err != nil {
    var multi *packersdk.MultiError
    if errors.As(err, &multi) {
        for _, e := range multi.Errors {
            if s := e.Error(); strings.Contains(s, "Failed cleaning up prior artifact") {
                log.Printf("manual cleanup needed (orphaned artifact): %v", e)
            }
        }
    }
    return err
}

Prevention

When it happens

Trigger: A post-processor artifact marked keep=false whose Destroy() implementation errors — e.g. the remote file/vagrant box/AMI it references cannot be deleted (permissions, already deleted, cloud API error).

Common situations: Cloud credentials lacking delete permissions (can create but not destroy resources); artifact file already removed externally;Destroy called on an artifact whose backing resource was reaped by a TTL; plugin bugs leaving Destroy unimplemented properly.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/1db81dc7ac920607. Report an issue: GitHub.