cilium/cilium · error

Invalid characters in MatchName: "%s". Only 0-9, a-z, A-Z an

Error message

Invalid characters in MatchName: "%s". Only 0-9, a-z, A-Z and ., -, _ characters are allowed

What it means

FQDNSelector.Validate checks MatchName against allowedMatchNameChars (^[-a-zA-Z0-9_.]+$): only alphanumerics, dot, dash, and underscore. This error means MatchName contains characters outside that set — most commonly wildcard characters like '*', which are only valid in MatchPattern.

Source

Thrown at pkg/policy/api/fqdn.go:105

// ToRegex function
func (s *FQDNSelector) IdentityLabel() labels.Label {
	match := s.MatchPattern
	if s.MatchName != "" {
		match = s.MatchName
	}

	return labels.NewLabel(match, "", labels.LabelSourceFQDN)
}

// Validate for FQDNSelector is a little wonky. While we do more processing
// when using MatchName the basic requirement is that is a valid regexp. We
// test that it can compile here.
func (s *FQDNSelector) Validate() error {
	if len(s.MatchName) > 0 && len(s.MatchPattern) > 0 {
		return fmt.Errorf("only one of MatchName or MatchPattern is allowed in an FQDNSelector")
	}
	if len(s.MatchName) > 0 && !allowedMatchNameChars.MatchString(s.MatchName) {
		return fmt.Errorf("Invalid characters in MatchName: \"%s\". Only 0-9, a-z, A-Z and ., -, _ characters are allowed", s.MatchName)
	}

	_, err := matchpattern.Validate(s.MatchPattern)
	return err
}

// ToRegex converts the given FQDNSelector to its corresponding regular
// expression. If the MatchName field is set in the selector, it performs all
// needed formatting to ensure that the field is a valid regular expression.
func (s *FQDNSelector) ToRegex() (*regexp.Regexp, error) {
	var preparedMatch string
	if s.MatchName != "" {
		preparedMatch = dns.FQDN(s.MatchName)
	} else {
		preparedMatch = matchpattern.Sanitize(s.MatchPattern)
	}

	regex, err := matchpattern.Validate(preparedMatch)

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Remove invalid characters; if you need wildcards, move the value to matchPattern instead.
  2. Use only 0-9, a-z, A-Z, '.', '-', '_' in matchName (it is a literal DNS name, not a regex).
  3. Strip scheme/port/whitespace: use the bare hostname, e.g. "api.example.com" not "https://api.example.com:443".
  4. Pre-validate with the same regex before submitting: regexp.MustCompile("^[-a-zA-Z0-9_.]+$").MatchString(matchName).

Example fix

// before (invalid)
fqdn:
  matchName: "*.example.com"
// after
fqdn:
  matchPattern: "*.example.com"
Defensive patterns

Strategy: validation

Validate before calling

var matchNameRe = regexp.MustCompile(`^[-a-zA-Z0-9_.]+$`)
func validMatchName(name string) bool { return matchNameRe.MatchString(name) }

Type guard

func isLiteralFQDN(s string) bool {
    return s != "" && regexp.MustCompile(`^[-a-zA-Z0-9_.]+$`).MatchString(s)
}

Try / catch

if err := sel.Validate(); err != nil {
    if strings.Contains(err.Error(), "Invalid characters in MatchName") {
        return fmt.Errorf("fix matchName %q: use a literal DNS name or move wildcards to matchPattern", sel.MatchName)
    }
    return err
}

Prevention

When it happens

Trigger: Setting FQDNSelector.MatchName to a value containing '*', '?', ':', spaces, uppercase-invalid punycode, or a protocol prefix like "https://api.example.com"; Validate() is called during policy import/validation.

Common situations: Users copying wildcard syntax (*.example.com) into matchName instead of matchPattern; pasting full URLs or ports (api.example.com:443) into matchName; typos or trailing whitespace/newline from YAML copy-paste.

Understand the failure class

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/038ff89251fb1380. Report an issue: GitHub.