hashicorp/packer · error

No communicator found for provisioners! This is usually beca

Error message

No communicator found for provisioners! This is usually because the
`communicator` config was set to "none". If you have any provisioners
then a communicator is required. Please fix this to continue.

What it means

The provisioner hook (Hook.Run) runs all provisioners for a build against a communicator. If comm is nil — meaning no communicator exists — but provisioners are registered, they could never run, so the hook returns this error explaining that `communicator: "none"` is incompatible with having provisioners.

Source

Thrown at packer/provisioner.go:123

			if ok {
				cast[keyString] = val
			} else {
				log.Printf("Error casting generated data key to a string.")
			}
		}
	}
	return cast
}

// Runs the provisioners in order.
func (h *ProvisionHook) Run(ctx context.Context, name string, ui packersdk.Ui, comm packersdk.Communicator, data interface{}) error {
	// Shortcut
	if len(h.Provisioners) == 0 {
		return nil
	}

	if comm == nil {
		return fmt.Errorf(
			"No communicator found for provisioners! This is usually because the\n" +
				"`communicator` config was set to \"none\". If you have any provisioners\n" +
				"then a communicator is required. Please fix this to continue.")
	}
	for _, p := range h.Provisioners {
		ts := CheckpointReporter.AddSpan(p.TypeName, "provisioner", p.Config)

		cast := CastDataToMap(data)
		err := p.Provisioner.Provision(ctx, ui, comm, cast)

		ts.End(err)
		if err != nil {
			return err
		}
	}

	return nil
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Remove all provisioner blocks from the template, or
  2. Change the source's `communicator` setting back to "ssh"/"winrm" and configure credentials.
  3. Move provisioning logic into the builder's own scripts or into image-building stages outside Packer if no communicator is truly desired.

Example fix

// before
source "null" "example" {
  communicator = "none"
}
provisioner "shell" { script = "setup.sh" } // error: no communicator
// after (option 1)
source "null" "example" { communicator = "none" } // no provisioner blocks
// after (option 2)
source "null" "example" {
  communicator = "ssh"
  ssh_username = "admin"
}
Defensive patterns

Strategy: validation

Validate before calling

// before hooking provisioners, ensure a communicator exists when needed
if len(hook.Provisioners) > 0 && comm == nil {
  return fmt.Errorf("provisioners declared but communicator is nil; check `communicator = \"none\"`")
}

Try / catch

if err := hook.Run(ctx, ui, comm, data, hookData); err != nil {
  if strings.Contains(err.Error(), "No communicator found") {
    // drop provisioners or enable ssh/winrm communicator
  }
}

Prevention

When it happens

Trigger: Calling ProvisionHook.Run (via packer/provisioner.go Hook.Run) with a nil communicator while h.Provisioners is non-empty; typically a build whose source sets `communicator = "none"` but still declares one or more `provisioner` blocks.

Common situations: Setting `communicator = "none"` on a builder/source to skip SSH/WinRM while forgetting to remove provisioner blocks; templates converted from builders that ignore the communicator setting; dynamically generated templates where provisioners are added unconditionally.

Related errors


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