hashicorp/packer · error

dots are not allowed

Error message

dots are not allowed

What it means

Plugin address parts must be single labels — dots would blur the boundary between hostname, namespace, and name segments. ParsePluginPart rejects any part containing '.', and as a side effect prevents punycode 'xn--' labels being smuggled in via dotted names.

Source

Thrown at hcl2template/addrs/plugin.go:75

// of an addrs.Plugin is already a hostname and it's ideal to use exactly
// the same case folding and normalization rules for all of the parts.
//
// It's valid to pass the result of this function as the argument to a
// subsequent call, in which case the result will be identical.
func ParsePluginPart(given string) (string, error) {
	if len(given) == 0 {
		return "", fmt.Errorf("must have at least one character")
	}

	// 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
}

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Remove dots from the plugin name/namespace part; use dashes instead
  2. Keep the structure hostname/namespace/name with no extra dots inside each part
  3. Use version constraints syntax (version = ">= 1.0.0") instead of encoding versions in the name

Example fix

// before
source = "github.com/hashicorp/my.plugin"
// after
source = "github.com/hashicorp/my-plugin"
Defensive patterns

Strategy: validation

Validate before calling

func hasNoDots(addr string) bool {
  for _, p := range strings.Split(addr, "/") { if strings.Contains(p, ".") && strings.Count(addr, "/") > 0 && isNameOrNs(p) { return false } }
  return true
}

Type guard

func validPluginPart(s string) bool { return len(s) > 0 && !strings.ContainsRune(s, '.') }

Prevention

When it happens

Trigger: Passing a part containing a dot, e.g. ParsePluginPart("my.plugin") or a required_plugins source like github.com/hashicorp/some.name where the name itself contains a dot.

Common situations: Users putting versions or file extensions in plugin names (amazon-1.0), or confusing the plugin address scheme with Go import paths.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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