hashicorp/packer · error

artifact is nil

Error message

artifact is nil

What it means

deriveSubjects in internal/provenance/subject.go refuses to operate on a nil packersdk.Artifact. Subject derivation (SHA-256 digests of artifact files, or a digest over the builder identity) requires a concrete artifact, so a nil input is rejected up front with a plain error. It is a defensive guard: callers passing a nil artifact have lost the build output somewhere upstream.

Source

Thrown at internal/provenance/subject.go:36

type DigestSet map[string]string

type Subject struct {
	Name   string    `json:"name"`
	Digest DigestSet `json:"digest"`
}

func DeriveSubjects(artifact packersdk.Artifact) ([]Subject, error) {
	return deriveSubjects(artifact)
}

func DeriveIdentityRecord(artifact packersdk.Artifact) (map[string]interface{}, error) {
	return deriveIdentityRecord(artifact)
}

func deriveSubjects(artifact packersdk.Artifact) ([]Subject, error) {
	if artifact == nil {
		return nil, fmt.Errorf("artifact is nil")
	}

	files := artifact.Files()
	if len(files) > 0 {
		subjects := make([]Subject, 0, len(files))
		for _, file := range files {
			digest, err := sha256File(file)
			if err != nil {
				return nil, fmt.Errorf("hash %q: %w", file, err)
			}

			subjects = append(subjects, Subject{
				Name: filepath.Base(file),
				Digest: DigestSet{
					"sha256": digest,
				},
			})
		}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Check artifact != nil before calling DeriveSubjects / DeriveIdentityRecord
  2. Verify the upstream builder actually produced an artifact (check build errors and artifact list length)
  3. In loops over artifacts, skip nil entries explicitly
  4. Wrap the call in error handling and degrade gracefully (skip provenance for that artifact)

Example fix

// before
subjects, err := provenance.DeriveSubjects(artifact)
// after
if artifact == nil {
    return nil // no artifact produced; skip provenance
}
subjects, err := provenance.DeriveSubjects(artifact)
Defensive patterns

Strategy: validation

Validate before calling

if artifact == nil {
    return nil, fmt.Errorf("no artifact produced by build; skipping provenance")
}
_ = artifact // safe to pass

Type guard

func isNilArtifact(a packersdk.Artifact) bool { return a == null || reflect.ValueOf(a).IsNil() }

Try / catch

subjects, err := provenance.DeriveSubjects(artifact)
if err != nil {
    if err.Error() == "artifact is nil" { log.Warn("no artifact; skipping subjects"); return nil }
    return err
}

Prevention

When it happens

Trigger: Calling DeriveSubjects(nil) or DeriveIdentityRecord(nil), or passing an artifact variable that a builder/plugin returned as nil (e.g. a build with no artifact) into those functions.

Common situations: A builder produced no artifact (failed or imageless build) and post-processing/provenance code still runs; iterating over multiple artifacts where one entry is nil; wiring a post-processor where artifact retrieval was skipped on error.

Related errors


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