hashicorp/packer · error

cannot use multiple consecutive dashes

Error message

cannot use multiple consecutive dashes

What it means

ParsePluginPart normalizes one component (host, org, type, or name) of a Packer plugin source address using IDNA lookup. It rejects strings containing '--' because consecutive dashes look confusing and would trigger the IDNA 'xn--' punycode interpretation path. This is a deliberate validation rule, not a bug.

Solutions

  1. Remove or replace consecutive dashes in the plugin source component with single dashes or other allowed characters
  2. Use only letters, digits, and single dashes, with no leading/trailing dashes
  3. If the real repository name contains '--', reference it via a different identifier or rename the repository/plugin

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 validPluginPart(s string) bool { return !strings.Contains(s, "--") }

Type guard

func isSafePluginPart(s string) bool { return s != "" && !strings.Contains(s, "--") }

Prevention

When it happens

Trigger: Calling ParsePluginPart (directly, or indirectly via ParsePluginSourceString or checkPluginNameNormalized) with a string containing two or more consecutive dashes, e.g. 'github.com/hashicorp/packer--plugin--foo'.

Common situations: Typos in plugin source addresses in required_plugins blocks; users copying repository names like 'packer-plugin-some--name'; attempts to encode separators with dashes; punycode/internationalized domain names containing '--'.

Related errors


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

Appendix: source

Thrown at hcl2template/addrs/plugin.go:84

	// We're going to process the given name using the same "IDNA" library we
	// use for the hostname portion, since it already implements the case
	// folding rules we want.
	//
	// 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

View on GitHub (pinned to eb36e3c3e4)