hashicorp/packer · error
malformed datasource reference %q, data sources must be comp
Error message
malformed datasource reference %q, data sources must be composed of 3 parts
What it means
newDataSourceRefString handles the 'data.*' branch of NewRefString and requires exactly three dot-separated segments: data.<type>.<name>. This error is thrown when a datasource reference has the right prefix ('data') but the wrong number of segments, so the datasource type and/or name cannot be identified.
Source
Thrown at hcl2template/types.refstring.go:79
}, 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",
Type: parts[1],
Name: parts[2],
}, nil
}
// getComponentByRef gets a registered component from the configuration from a refString
func (cfg *PackerConfig) getComponentByRef(rs refString) (interface{}, error) {
switch rs.MType {
case "data":
for _, ds := range cfg.Datasources {
if ds.Type != rs.Type {
continue
}View on GitHub (pinned to eb36e3c3e4)
Solutions
- Use the full three-part form: data.<datasource-type>.<datasource-name>, e.g. data.amazon-ami.my_ami.
- If you need an output field of the datasource, reference the specific attribute after resolving the block, not inside the refString itself.
- Count the dots: exactly two dots are required in a data.* reference.
- If the type label is unknown, check the datasource plugin name in the template's required_plugins block and use that as <type>.
Example fix
// before
rs, err := NewRefString("data.my_ami")
// after
rs, err := NewRefString("data.amazon-ami.my_ami") Defensive patterns
Strategy: validation
Validate before calling
func validDataSourceRef(s string) bool {
parts := strings.Split(s, ".")
return len(parts) == 3 && parts[0] == "data"
}
// guard before: NewRefString("data.amazon-ami.my_ami") Type guard
func isThreePartDataRef(s string) bool {
parts := strings.Split(s, ".")
return len(parts) == 3 && parts[0] == "data" && parts[1] != "" && parts[2] != ""
} Try / catch
rs, err := NewRefString(ref)
if err != nil {
return fmt.Errorf("malformed data source ref %q (need data.<type>.<name>): %w", ref, err)
} Prevention
- Memorize the shape: data.<plugin-type>.<block-name> — two dots, three segments.
- Do not append attribute names (.id, .name) to a refString; resolve the block first.
- When referencing a var/local, do not reuse the two-part form for data sources.
When it happens
Trigger: Calling NewRefString with 'data.<name>' (2 parts, type missing), 'data.<type>' alone, 'data.<type>.<name>.<extra>' (4+ parts), or bare 'data' (1 part).
Common situations: Writing ${data.my_ami} in a template instead of ${data.amazon-ami.my_ami}; copy-pasting a var/local style two-part reference for a datasource; accidentally appending an attribute like data.amazon-ami.my_ami.id into a context that expects only the block reference.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unsupported reftype %q, must be either 'data', 'local' or 'v
- unsupported dependency type %q; datasources can only depend
- unable to find source vertex %q for dependency analysis, thi
- could not get dependency %q for %q, %q missing in template
- failed to get datasource '%s.%s': component unknown
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/fb76c3e9824f1211.
Report an issue: GitHub.