hashicorp/packer · error

failed to get datasource '%s.%s': component unknown

Error message

failed to get datasource '%s.%s': component unknown

What it means

getComponentByRef resolves a parsed refString against the blocks registered in the PackerConfig. For a 'data' refString it scans cfg.Datasources for a block whose Type and DSName both match; this error is thrown when no registered datasource matches, i.e. the referenced data.<type>.<name> block is unknown to the configuration.

Source

Thrown at hcl2template/types.refstring.go:103

		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
			}
			if ds.DSName != rs.Name {
				continue
			}
			return ds, nil
		}
		return nil, fmt.Errorf("failed to get datasource '%s.%s': component unknown", rs.Type, rs.Name)
	case "local":
		for _, loc := range cfg.LocalBlocks {
			if loc.LocalName != rs.Name {
				continue
			}
			return loc, nil
		}
	case "var":
		for _, val := range cfg.InputVariables {
			if val.Name != rs.Name {
				continue
			}
			return val, nil
		}
	}

	return nil, fmt.Errorf("Unsupported component: %q, only vars, locals and datasources can be fetched by their refString", rs)
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Add the missing datasource block to the template, e.g. data "amazon-ami" "my_ami" { ... }.
  2. Verify the reference's type and name exactly match the datasource block's labels (case-sensitive).
  3. If the block was renamed, update every ${data.<type>.<name>} reference to the new name.
  4. Confirm the file containing the datasource block is part of the template being built.

Example fix

// before (reference with no matching block)
locals { ami_id = data.amazon-ami.my_ami.id }
// after (declare the block)
data "amazon-ami" "my_ami" { filters = { name = "ubuntu-*" } }
locals { ami_id = data.amazon-ami.my_ami.id }
Defensive patterns

Strategy: validation

Validate before calling

// before evaluating, verify the datasource block exists in the parsed config
found := false
for _, ds := range cfg.Datasources {
	if ds.Type == dsType && ds.DSName == dsName {
		found = true
		break
	}
}
if !found {
	return fmt.Errorf("datasource %s.%s not declared in template", dsType, dsName)
}

Type guard

func hasDatasource(cfg *hcl2template.PackerConfig, dsType, dsName string) bool {
	for _, ds := range cfg.Datasources {
		if ds.Type == dsType && ds.DSName == dsName {
			return true
		}
	}
	return false
}

Try / catch

comp, err := cfg.getComponentByRef(rs)
if err != nil {
	return fmt.Errorf("cannot resolve %s: %w — check the data block is declared with matching type/name labels", rs, err)
}

Prevention

When it happens

Trigger: Calling getComponentByRef (via recursivelyEvaluateLocalVariable while evaluating a local) with a data refString whose Type/Name pair is not present in cfg.Datasources — the datasource block was never declared, or was declared with a different type or name.

Common situations: Typo in the datasource name or type in ${data.type.name}; datasource block deleted or renamed while references remain; datasource declared in a different template/file not included in this build; plugin type label mismatch (e.g. 'amazon-ami' vs 'amazon-ami' with different source path).

Related errors


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