cloudflare/cloudflared · error
invalid HTTP status code
Error message
invalid HTTP status code
What it means
Ingress rules can use a 'http_status:CODE' service to return a fixed HTTP status. This error is wrapped when the text after 'http_status:' cannot be parsed as an integer by strconv.Atoi. The ingress config is rejected entirely and ParseIngress returns an Ingress{} zero value with this error.
Source
Thrown at ingress/ingress.go:261
}
func validateIngress(ingress []config.UnvalidatedIngressRule, defaults OriginRequestConfig) (Ingress, error) {
rules := make([]Rule, len(ingress))
for i, r := range ingress {
cfg := setConfig(defaults, r.OriginRequest)
var service OriginService
if prefix := "unix:"; strings.HasPrefix(r.Service, prefix) {
// No validation necessary for unix socket filepath services
path := strings.TrimPrefix(r.Service, prefix)
service = &unixSocketPath{path: path, scheme: "http"}
} else if prefix := "unix+tls:"; strings.HasPrefix(r.Service, prefix) {
path := strings.TrimPrefix(r.Service, prefix)
service = &unixSocketPath{path: path, scheme: "https"}
} else if prefix := "http_status:"; strings.HasPrefix(r.Service, prefix) {
statusCode, err := strconv.Atoi(strings.TrimPrefix(r.Service, prefix))
if err != nil {
return Ingress{}, errors.Wrap(err, "invalid HTTP status code")
}
if statusCode < 100 || statusCode > 999 {
return Ingress{}, fmt.Errorf("invalid HTTP status code: %d", statusCode)
}
srv := newStatusCode(statusCode)
service = &srv
} else if r.Service == HelloWorldFlag || r.Service == HelloWorldService {
service = new(helloWorld)
} else if r.Service == ServiceSocksProxy {
rules := make([]ipaccess.Rule, len(r.OriginRequest.IPRules))
for i, ipRule := range r.OriginRequest.IPRules {
rule, err := ipaccess.NewRuleByCIDR(ipRule.Prefix, ipRule.Ports, ipRule.Allow)
if err != nil {
return Ingress{}, fmt.Errorf("unable to create ip rule for %s: %s", r.Service, err)
}
rules[i] = rule
}View on GitHub (pinned to 2253eeeb25)
Solutions
- Make the service value exactly 'http_status:<integer>', e.g. http_status:404 with no extra text.
- Quote the YAML value if it may be misinterpreted: service: "http_status:404".
- Note a separate check requires 100 <= code <= 999; pick a code in that range to avoid the sibling error.
Example fix
// before service: http_status: Not Found // after service: http_status:404
Defensive patterns
Strategy: validation
Validate before calling
func validHTTPStatusService(svc string) error {
const prefix = "http_status:"
if !strings.HasPrefix(svc, prefix) {
return nil
}
code, err := strconv.Atoi(strings.TrimPrefix(svc, prefix))
if err != nil {
return fmt.Errorf("http_status must be an integer, got %q", svc)
}
if code < 100 || code > 999 {
return fmt.Errorf("http_status code %d out of range 100-999", code)
}
return nil
} Try / catch
ing, err := ingress.ParseIngress(conf)
if err != nil {
return fmt.Errorf("invalid ingress config: %w", err)
} Prevention
- Always use the exact form http_status:<digits>, no spaces or extra text.
- Run `cloudflared tunnel ingress validate` after editing config.yml.
- Quote YAML values containing colons.
When it happens
Trigger: An ingress rule with service like 'http_status: twohundred', 'http_status: 200 OK', 'http_status:' (empty), or any non-numeric suffix so strconv.Atoi fails.
Common situations: Hand-edited config.yml with a typo or stray text in the status code, YAML quoting mistakes, or copy-pasting 'http_status:404 ' with trailing characters.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid HTTP status code: %d
- Rule #%d has an invalid regex
- No configuration file was found. Please create one, or use t
- cloudflared tunnel rule expects a single argument, the URL t
- ErrNoIngressRules
AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06).
Data as JSON: /api/errors/a20d96483a068ada.
Report an issue: GitHub.