hashicorp/packer · error

unsupported reftype %q, must be either 'data', 'local' or 'v

Error message

unsupported reftype %q, must be either 'data', 'local' or 'var'

What it means

NewRefString parses a dotted reference string (data.<type>.<name>, var.<name>, local.<name>) into a refString struct. This error is thrown when the first segment of the string is none of 'data', 'local', or 'var', meaning the string does not reference a component type Packer knows how to resolve. It is a parse-time guard so unsupported roots fail fast instead of producing a bogus refString.

Source

Thrown at hcl2template/types.refstring.go:66

	}

	return refString{}, fmt.Errorf("unsupported refstring %q, must be of 'data', 'local' or 'var' type", t)
}

func NewRefString(rs string) (refString, error) {
	parts := strings.Split(rs, ".")

	switch parts[0] {
	case "local", "var":
		return refString{
			MType: parts[0],
			Name:  parts[1],
		}, nil
	case "data":
		return newDataSourceRefString(parts)
	}

	return refString{}, fmt.Errorf("unsupported reftype %q, must be either 'data', 'local' or 'var'", parts[0])
}

func (rs refString) String() string {
	if rs.Type == "" {
		return fmt.Sprintf("%s.%s", rs.MType, rs.Name)
	}

	return fmt.Sprintf("%s.%s.%s", rs.MType, rs.Type, rs.Name)
}

func newDataSourceRefString(parts []string) (refString, error) {
	if len(parts) != 3 {
		return refString{}, fmt.Errorf("malformed datasource reference %q, data sources must be composed of 3 parts",
			strings.Join(parts, "."))
	}

	return refString{
		MType: "data",

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Fix the reference string to start with 'data.', 'local.', or 'var.' as appropriate.
  2. If referencing a datasource, use the full three-part form data.<type>.<name> (e.g. data.amazon-ami.my_ami).
  3. If the refString is built programmatically, prefix it with the correct component type before calling NewRefString, or use NewRefStringFromDep with a valid hcl.Traversal.
  4. Check for typos and extra/missing dots that shift which segment becomes parts[0].

Example fix

// before
rs, err := NewRefString("amazon-ami.my_ami")
// after
rs, err := NewRefString("data.amazon-ami.my_ami")
Defensive patterns

Strategy: validation

Validate before calling

func validRefString(s string) bool {
	parts := strings.Split(s, ".")
	switch parts[0] {
	case "local", "var":
		return len(parts) == 2
	case "data":
		return len(parts) == 3
	}
	return false
}
// guard: if !validRefString(ref) { fix before NewRefString(ref) }

Type guard

func isSupportedRefRoot(s string) bool {
	root := strings.SplitN(s, ".", 2)[0]
	return root == "data" || root == "local" || root == "var"
}

Try / catch

rs, err := NewRefString(ref)
if err != nil {
	return fmt.Errorf("invalid reference %q: %w", ref, err)
}

Prevention

When it happens

Trigger: Calling NewRefString (directly or via NewRefStringFromDep with a traversal whose root is not data/local/var) with a string whose first dot-segment is something else, e.g. "resource.foo", "aws_instance.web", "myvar.x", or an empty string (parts[0] == "").

Common situations: Typo in a template reference like ${dataa.source} or forgetting the prefix entirely and writing just the datasource name; using Terraform-style roots unsupported by Packer such as module.* or resource.*; programmatic/plugin code building dependency strings by hand with the wrong prefix.

Related errors


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