hashicorp/packer · error
must contain only letters, digits, and dashes, and may not u
Error message
must contain only letters, digits, and dashes, and may not use leading or trailing dashes: %w
What it means
ParsePluginPart runs idna.Lookup.ToUnicode on the plugin source component. If that fails, the component is not a valid IDNA label: it must contain only letters, digits, and dashes, without leading or trailing dashes. The IDNA library error is wrapped with %w for inspection.
Source
Thrown at hcl2template/addrs/plugin.go:89
// The idna library doesn't expose individual label parsing directly, but
// once we've verified it doesn't contain any dots we can just treat it
// like a top-level domain for this library's purposes.
if strings.ContainsRune(given, '.') {
return "", fmt.Errorf("dots are not allowed")
}
// We don't allow names containing multiple consecutive dashes, just as
// a matter of preference: they look confusing, or incorrect.
// This also, as a side-effect, prevents the use of the "punycode"
// indicator prefix "xn--" that would cause the IDNA library to interpret
// the given name as punycode, because that would be weird and unexpected.
if strings.Contains(given, "--") {
return "", fmt.Errorf("cannot use multiple consecutive dashes")
}
result, err := idna.Lookup.ToUnicode(given)
if err != nil {
return "", fmt.Errorf("must contain only letters, digits, and dashes, and may not use leading or trailing dashes: %w", err)
}
return result, nil
}
// IsPluginPartNormalized compares a given string to the result of ParsePluginPart(string)
func IsPluginPartNormalized(str string) (bool, error) {
normalized, err := ParsePluginPart(str)
if err != nil {
return false, err
}
if str == normalized {
return true, nil
}
return false, nil
}
// ParsePluginSourceString parses the source attribute and returns a plugin.View on GitHub (pinned to eb36e3c3e4)
Solutions
- Replace invalid characters (underscores, dots, symbols) with dashes or remove them
- Remove any leading or trailing dashes from the component
- Verify the source address against the documented format 'github.com/org/name'
Example fix
// before source "github.com/hashicorp/packer_plugin_amazon" // after source "github.com/hashicorp/packer-plugin-amazon"
Defensive patterns
Strategy: validation
Validate before calling
func validChars(s string) bool {
for _, r := range s {
if !(r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z' || r >= '0' && r <= '9' || r == '-') { return false }
}
return len(s) > 0 && s[0] != '-' && s[len(s)-1] != '-'
} Type guard
func isIDNASafe(s string) bool { _, err := idna.Lookup.ToUnicode(s); return err == nil } Prevention
- Replace underscores with dashes in plugin identifiers
- Reject or sanitize non-ASCII/symbol characters before building source strings
- Trim leading/trailing dashes from user-supplied names
When it happens
Trigger: ParsePluginPart (or ParsePluginSourceString / checkPluginNameNormalized) given a component with characters outside [a-zA-Z0-9-], or one starting/ending with '-', e.g. 'github.com/hashicorp/packer_plugin', '-amazon-', or 'amazon!'.
Common situations: Underscores in plugin names (common mistake, since repos often use them); special characters from copy-paste; trailing dash left from editing; uppercase is fine but symbols are not.
Related errors
- cannot use multiple consecutive dashes
- The provided source URL is invalid. The following errors hav
- Invalid plugin type %q in source: %s"
- Plugin source has a type with the prefix %q, which isn't val
- Plugin source has a type with the %q prefix, which isn't val
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/ea82ec947c8a13fe.
Report an issue: GitHub.