Configuration: HTTP response control

This page documents directives for returning custom status codes, aborting connections, IP-based access control, and 103 Early Hints responses.

Info

Directives

Custom status codes

  • status <code: integer> (http-response)
    • This directive specifies an HTTP status code to return. In block form, supports nested url, regex, body, and location directives. Default: none

Block form options

Nested directiveArgumentsDescriptionDefault
url<string>Only apply this status to requests matching this exact path.all requests
regex<string>Only apply this status to requests matching this regular expression.all requests
body<string>Response body to include.empty body
location<string>Redirect destination for 3xx responses.no redirect

Configuration example:

example.com {
    status 503 {
        body "Service temporarily unavailable"
    }

    status 404 {
        url "/old-endpoint"
        body "This endpoint has been removed"
    }

    status 301 {
        url "/legacy"
        location "/new"
    }

    status 410 {
        regex "^/api/v1/.*"
        body "API v1 has been deprecated"
    }
}

Multiple status directives can be defined. They are evaluated in order — the first matching rule wins.

Connection abort

  • abort [bool: boolean] (http-response)
    • This directive specifies whether the connection is immediately closed without sending any response. When true or when omitted, the connection is terminated immediately. Default: abort false

Configuration example:

example.com {
    abort
}

When abort is set, the connection is terminated immediately with no HTTP response sent. This is useful for silently dropping requests from unwanted clients or for denial-of-service mitigation.

IP access control

  • block <ip-or-cidr: string>... (http-response)
    • This directive specifies one or more IP addresses or CIDR ranges to block. Blocked IPs receive a 403 Forbidden response. Default: none
  • allow <ip-or-cidr: string>... (http-response)
    • This directive specifies one or more IP addresses or CIDR ranges to allow. When configured, only the listed IPs/CIDRs are permitted. All other IPs receive a 403 Forbidden response. Default: none (all allowed)

Configuration example:

example.com {
    block "192.168.1.100" "10.0.0.50"
    block "203.0.113.0/24"

    allow "10.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16"
}

Combined block and allow

When both block and allow are configured:

  1. If the IP matches an allow entry and a block entry → blocked (block takes precedence)
  2. If the IP matches only an allow entry → allowed
  3. If the IP matches only a block entry → blocked
  4. If the IP matches neither → allowed (unless the allow list is non-empty, in which case non-listed IPs are denied)
example.com {
    allow "192.168.1.0/24"
    block "192.168.1.100"
}

In this example: 192.168.1.50 → allowed, 192.168.1.100 → blocked, 10.0.0.1 → denied.

103 Early Hints

  • early_hints (http-response)
    • This directive specifies a 103 Early Hints response to send before the final response is ready. The 103 response includes Link headers that allow the browser to begin preloading resources (stylesheets, scripts, fonts, etc.) while the server is still preparing the final response. Default: none

Subdirectives

SubdirectiveArgumentsDescriptionDefault
link<string>A Link header value to include in the 103 response. Multiple link entries produce multiple Link headers.none

Configuration example:

example.com {
    early_hints {
        link "</assets/main.css>; rel=preload; as=style"
        link "</assets/main.js>; rel=preload; as=script"
        link "</fonts/inter.woff2>; rel=preload; as=font; crossorigin"
    }
}

Multiple link entries can be defined within a single early_hints block. Multiple early_hints blocks can also be defined at different scoping levels (host, location, if / if_not).

HTTP/1.1 support

By default, 103 Early Hints is supported natively on HTTP/2 and HTTP/3 connections. For HTTP/1.1, you must enable support via the h1_enable_early_hints directive in your http block:

{
    http {
        h1_enable_early_hints true
    }
}

Without this option, 103 Early Hints is silently skipped on HTTP/1.1 connections (a warning is logged).

Note

103 Early Hints is only effective on HTTP/2+ connections by default. For HTTP/1.1, enable h1_enable_early_hints true in your http block. If send_early_hints fails, a warning is logged and the request continues normally.

Scoping

The early_hints directive can be placed at different configuration levels:

  • Host level — applies to all requests for that host
  • location block — applies only to requests matching that path prefix
  • if / if_not blocks — applies conditionally based on a matcher

Scoping

All directives (status, abort, block, allow, early_hints) can be placed at different configuration levels:

  • Host level — applies to all requests for that host
  • location block — applies only to requests matching that path prefix
  • if / if_not blocks — applies conditionally based on a matcher

Observability

Metrics

MetricTypeAttributesDescription
ferron.response.abortedCounterConnections aborted via the abort directive
ferron.response.ip_blockedCounterConnections blocked via block/allow directives. Does not include raw IP addresses
ferron.response.status_rule_matchedCounterhttp.response.status_code, ferron.rule_idCustom status codes returned via status directives