hashicorp/packer · error

failed to compute destination path %q: %s

Error message

failed to compute destination path %q: %s

What it means

This error is returned when the optional user-facing destination (p.config.Destination) is set, but p.getUserDestination() fails to compute the concrete user file path from it. The configured Destination template/path is invalid for the path-expansion logic (e.g. bad template variables or unusable path expression), so the raw SBOM was never written for the user.

Source

Thrown at provisioner/hcp-sbom/provisioner.go:912

	}
	defer func() {
		_ = outFile.Close() // Cleanup, ignore error
	}()

	err = json.NewEncoder(outFile).Encode(PackerSBOM{
		RawSBOM: sbomData,
		Format:  format,
		Name:    p.config.SbomName,
	})
	if err != nil {
		return fmt.Errorf("failed to write SBOM to %q: %s", pkrDst, err)
	}

	// Also save to user destination if specified
	if p.config.Destination != "" {
		usrDst, err := p.getUserDestination()
		if err != nil {
			return fmt.Errorf("failed to compute destination path %q: %s", p.config.Destination, err)
		}
		if err := os.WriteFile(usrDst, sbomData, 0644); err != nil {
			return fmt.Errorf("failed to write SBOM to destination %q: %s", usrDst, err)
		}
	}

	return nil
}

// Communicator returns the communicator for elevated execution
func (p *Provisioner) Communicator() packersdk.Communicator {
	return p.communicator
}

// ElevatedUser returns the elevated user for Windows execution
func (p *Provisioner) ElevatedUser() string {
	return p.config.ElevatedUser
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Read the wrapped error to see which part of the path expansion failed.
  2. Simplify the destination to a plain writable path (e.g. ./sbom.json or /tmp/sbom.json) and rebuild.
  3. If using Packer template variables in destination, use only supported ones (e.g. build-specific variables) with correct syntax {{ .VarName }}.
  4. Verify path separators are valid for the OS where Packer runs.
  5. Clear or unset destination if you only need the HCP-internal copy.

Example fix

// before (HCL)
destination = "/out/{{ .Bogus }}/sbom.json"
// after
destination = "/out/{{ build `ID` }}/sbom.json"  // or a static path: "/out/sbom.json"
Defensive patterns

Strategy: validation

Validate before calling

if cfg.Destination != "" {
	extended, err := interpolate.Render(cfg.Destination, ctxData)
	if err != nil {
		return fmt.Errorf("invalid destination %q: %w", cfg.Destination, err)
	}
	if filepath.Clean(extended) == "" || strings.HasSuffix(extended, string(os.PathSeparator)) {
		return fmt.Errorf("destination %q must be a file path", cfg.Destination)
	}
}

Prevention

When it happens

Trigger: config.Destination is non-empty and getUserDestination() returns an error while expanding/validating the configured destination path — for example an unknown template variable, malformed path, or the expansion function returning an error for the given string.

Common situations: Users set destination with unsupported template syntax (misspelled variables like {{ .Foo }}), an absolute path with invalid characters on Windows, or a path referencing data not available at provision time.

Related errors


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