caddyserver/caddy · error

converting hostname '%s' to ASCII: %v

Error message

converting hostname '%s' to ASCII: %v

What it means

MatchHost.Provision normalizes every `host` matcher entry with x/net/idna ToASCII before lowercasing and de-duplicating. If a host cannot be converted to punycode (malformed labels, bad characters, over-long labels), provisioning fails with this error naming the host.

Source

Thrown at modules/caddyhttp/matchers.go:263

	// iterate to merge multiple matchers into one
	for d.Next() {
		*m = append(*m, d.RemainingArgs()...)
		if d.NextBlock(0) {
			return d.Err("malformed host matcher: blocks are not supported")
		}
	}
	return nil
}

// Provision sets up and validates m, including making it more efficient for large lists.
func (m MatchHost) Provision(_ caddy.Context) error {
	// check for duplicates; they are nonsensical and reduce efficiency
	// (we could just remove them, but the user should know their config is erroneous)
	seen := make(map[string]int, len(m))
	for i, host := range m {
		asciiHost, err := idna.ToASCII(host)
		if err != nil {
			return fmt.Errorf("converting hostname '%s' to ASCII: %v", host, err)
		}
		normalizedHost := strings.ToLower(asciiHost)
		if firstI, ok := seen[normalizedHost]; ok {
			return fmt.Errorf("host at index %d is repeated at index %d: %s", firstI, i, host)
		}
		// Normalize exact hosts for standardized comparison in large-list fastpath later on.
		// Keep wildcards/placeholders untouched.
		if m.fuzzy(asciiHost) {
			m[i] = asciiHost
		} else {
			m[i] = normalizedHost
		}
		seen[normalizedHost] = i
	}

	if m.large() {
		// sort the slice lexicographically, grouping "fuzzy" entries (wildcards and placeholders)
		// at the front of the list; this allows us to use binary search for exact matches, which

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Correct the hostname: no spaces, no empty labels, labels ≤63 chars, valid characters only.
  2. For internal names with underscores, test the exact entry against idna.ToASCII; if rejected, rename the service or match on a different field.
  3. Quote and lint host lists when generating config to catch stray characters.

Example fix

// before (Caddyfile)
@ok host "exa mple.com"

// after
@ok host example.com
Defensive patterns

Strategy: validation

Validate before calling

import "golang.org/x/net/idna"

func validHostnames(hosts []string) bool {
	for _, h := range hosts {
		if _, err := idna.ToASCII(h); err != nil {
			return false
		}
	}
	return true
}

Prevention

When it happens

Trigger: `host` matcher entries like "exa mple.com" (space), "-leadinghyphen.example.com", labels longer than 63 chars, empty labels ("a..com"), or characters the IDNA profile rejects such as underscores in strict profiles.

Common situations: Wildcard/certificate-san lists pasted with invisible whitespace; underscores in internal hostnames (some older Caddy versions tolerated `_` in host matchers, newer IDNA handling is stricter); U-labels with combining marks that fail validation.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/1cd87cad2b04691f. Report an issue: GitHub.