caddyserver/caddy · error
%s: entry %q has '*' in an invalid position (only a trailing
Error message
%s: entry %q has '*' in an invalid position (only a trailing '*' is allowed)
What it means
Header alias allowlist entries support only a single trailing '*' as a wildcard. This error fires when '*' appears anywhere else in the name (after trimming a trailing '*'), e.g. a leading or middle asterisk. Such patterns are not supported by the precomputed exact/prefix matching structures the filter builds.
Source
Thrown at modules/caddyhttp/server.go:406
for _, entry := range entries {
// Reject non-ASCII bytes: Go's HTTP parser returns 400 for
// non-ASCII header names, so such entries can never match.
for i := 0; i < len(entry); i++ {
if entry[i] >= 0x80 {
return nil, nil, nil, fmt.Errorf("%s: entry %q contains non-ASCII characters", directive, entry)
}
}
isGlob := strings.HasSuffix(entry, "*")
name := entry
if isGlob {
name = strings.TrimSuffix(entry, "*")
}
// Reject entries with '*' not at the trailing position.
if strings.ContainsRune(name, '*') {
return nil, nil, nil, fmt.Errorf("%s: entry %q has '*' in an invalid position (only a trailing '*' is allowed)", directive, entry)
}
// The name (without trailing '*') must contain at least one separator.
if !strings.ContainsRune(name, sep) {
return nil, nil, nil, fmt.Errorf("%s: entry %q does not contain a %q", directive, entry, sep)
}
canonAllow := http.CanonicalHeaderKey(name)
canonDrop := http.CanonicalHeaderKey(strings.ReplaceAll(name, string(sep), "-"))
if isGlob {
prefixRules = append(prefixRules, aliasPrefixRule{
allow: canonAllow,
drop: canonDrop,
})
} else {
exactAllow[canonAllow] = struct{}{}
exactDrop[canonDrop] = struct{}{}View on GitHub (pinned to 50e54ee279)
Solutions
- Move the wildcard to the end: use "prefix*" not "*suffix" or "a*b"
- For leading-wildcard needs, enumerate explicit entries instead
- Re-validate the config after the change
Example fix
// before "-": ["*api.internal"] // after "-": ["x_api.internal", "stage-x_api*"]
Defensive patterns
Strategy: validation
Validate before calling
func validWildcard(entry string) error {
name := strings.TrimSuffix(entry, "*")
if strings.ContainsRune(name, '*') {
return fmt.Errorf("%q: '*' only allowed as trailing character", entry)
}
return nil
} Prevention
- Treat allowlist entries as 'exact name' or 'prefix*' only
- Enumerate exceptions instead of inventing mid-string globs
When it happens
Trigger: An allowlist entry like "*api.example.com" or "X-*Api*" in the header alias config; only "X_Api*" style trailing globs are legal.
Common situations: Assuming full glob/fnmatch semantics when writing allowlist entries; porting wildcard patterns from other proxies.
Related errors
- replacement %d for header field '%s': %v
- cannot specify both a substring search and a regular express
- %s: entry %q contains non-ASCII characters
- %s: entry %q does not contain a %q
- server %s: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/7fde2a2d20cede66.
Report an issue: GitHub.