github ferronweb/ferron 3.0.0-beta.3

pre-release6 hours ago

Breaking changes

If you are upgrading to this beta version, you must update your configuration files to accommodate the following syntax refactors:

  • Removed force_trace directive - the force_trace directive has been removed as trace context creation is now always enabled for every request. Configurations using force_trace true should remove the directive; configurations using force_trace false should also remove it since the behavior now matches the default.
  • Default text log format changed - the default text access log format has been changed from Combined Log Format to Enhanced Combined Log Format, which adds Host header and trace ID fields. If you rely on the default text log format and want to keep the previous behavior, explicitly set the pattern to the Combined Log Format using access_pattern "%client_ip - %auth_user [%t] \"%method %path_and_query %version\" %status %content_length \"%{Referer}i\" \"%{User-Agent}i\"" in your log block.
  • Circuit breaker 5xx responses no longer counted by default - upstream 5xx responses no longer trip the circuit breaker unless record_5xx true is explicitly set. This makes the circuit breaker purely transport-failure-based by default, giving operators explicit control over Layer 7 error sensitivity.
  • passive_check directive removed - the passive_check directive has been replaced with a more generic circuit_breaker directive that supports passive health checking and circuit breaking for both HTTP and gRPC services.

Added

Modules

  • http-variables - a new module for setting interpolation variables based on request conditions and mapping variables to custom access log fields.

Security

  • Custom abuse event registration - it's now possible to register custom abuse events, for example, for honeypots.

Observability & metrics

  • Reload metrics and logs - the new metrics-reload module emits application log events and a ferron.reloads counter metric around configuration reloads, with a ferron.reload.successful attribute indicating success or failure and an error.message attribute on failures.
  • Abuse ban logging - the abuse ban logger now logs at the WARN level when an IP is triggered for banning, including the banned IP address and reason.

HTTP server core

  • set_var directive - new directive for setting interpolation variables based on regex matching against request attributes, with optional value, case_insensitive, and negate subdirectives. (http-variables)
  • log_field directive - new directive for mapping any resolvable variable (including interpolated strings) to custom access log field names, evaluated after the response is generated. (http-variables)
  • Support for date-based caching - the If-Modified-Since header is now supported for static file responses, allowing clients to cache responses and avoid unnecessary re-downloads when the file has not been modified.
  • Auth user variable support - the auth.user variable is now available in variable interpolations for the HTTP server.
  • Trace ID and span ID variable support - the trace.id and trace.spanid variables are now available in variable interpolations for the HTTP server.

HTTP caching

  • RFC 9111 conditional request revalidation - when a client sends Cache-Control: max-age=0 or no-cache, the HTTP cache now performs conditional revalidation using stored ETag and Last-Modified validators instead of bypassing the cache entirely. If the upstream returns 304 Not Modified, the cached response body is served with fresh headers. If the upstream returns 200 OK (content changed), the cached entry is replaced. (http-cache)
  • stale-while-revalidate support - when a cached response's max-age has expired but a stale-while-revalidate directive is present, the stale response is served immediately to the client while the cache entry remains available within the stale window. This avoids latency spikes for expired cache entries. (http-cache)
  • stale-if-error support - when an upstream revalidation request returns a 5xx error and a stale-if-error directive is present on the cached response, the stale cached response is served instead of the error. This provides resilience against backend failures. (http-cache)
  • must-revalidate and proxy-revalidate enforcement - entries with must-revalidate or proxy-revalidate directives (or s-maxage, which implies proxy-revalidate) are never served stale, even within stale-while-revalidate or stale-if-error windows. (http-cache)
  • Ignore request cache control - when ignore_request_cache_control in cache is enabled, request-based cache control (e.g., Cache-Control: no-cache) is ignored in favor of the configured cache policy.
  • Cache purge propagation - when a cache purge occurs (via PURGE method or X-LiteSpeed-Purge header), the purge can be propagated to other instances via an external control-plane service. Edge instances send webhook POST requests to a configured control-plane URL, which broadcasts PURGE requests to all other registered edges. Loop prevention is handled via the X-Purge-Source: propagation header and origin exclusion. (http-cache)

Automatic TLS

  • HTTP auth for on-demand ask endpoint - when on_demand_ask_auth is configured, HTTP Basic Auth credentials are used for the on-demand ask endpoint, allowing for secure access to the endpoint.
  • Fallback ACME providers — the fallback directive allows configuring multiple ACME providers with sequential failover. When the primary provider fails (e.g., CA outage), Ferron automatically tries the next configured fallback. Each provider maintains its own cached credentials. (tls-acme)

HTTP TLS provider

  • On-demand certificate fetching — the tls-http module now supports on-demand (lazy) certificate retrieval. When on_demand true is set in a wildcard host block (e.g., *:443), certificates are fetched on the first TLS handshake for each SNI hostname, rather than polling a single endpoint at startup.
  • On-demand approval endpoint — the new on_demand_ask, on_demand_ask_auth, and on_demand_ask_no_verification directives control an authorization endpoint that is consulted before fetching a certificate for a hostname. The hostname is sent as a ?domain=<encoded> query parameter.
  • Per-SNI certificate refresh — on-demand fetched certificates are individually refreshed at the configured refresh_interval, ensuring certificate rotation is applied per hostname without affecting other SNIs.

Utilities

  • Formatter utility - a new ferron-fmt command-line tool is available for formatting and validating Ferron configuration files.

Changed

Admin API

  • Reload failure status - the /reload endpoint now returns an error message in the response body when reload fails. Previously, it only indicated that reloading was initiated without any details about why it failed.

Observability & logging

  • Improved error reporting in structured logs - reverse proxy, HTTP, TCP and QUIC error logs now include an error.message attribute when available. Also, some of the reverse proxy error log summaries being overly long have been fixed.
  • OCSP response caching log improvements - OCSP response caching logs are now emitted at info level by default. The ferron.ocsp.cert.primary_san attribute is also included in the log message when available.
  • Trace context always enabled - the force_trace directive has been removed, as trace context creation is now always enabled for every request. Additionally, when no tracing export is configured, Ferron will not generate a new span ID for incoming requests, avoiding unnecessary overhead.

TLS & ACME

  • ACME provisioning cycle log improvements - ACME provisioning logs are now no longer emitted at debug level when a certificate is still valid or loaded from cache, as these messages were redundant with the ferron.acme.domains attribute already included in the main log message.

Proxying

  • Forward proxying CONNECT cycle log improvements - CONNECT connection closure logs are now no longer emitted at debug level when a tunnel is closed to reduce noise in the application logs.
  • Circuit breaker record_5xx toggle - the circuit_breaker directive now supports a record_5xx subdirective (default: false) to control whether upstream 5xx responses count toward tripping the circuit.

Fixed

Observability & logging

  • HTTP/2 and /3 host header log visbility fix - HTTP/2 and HTTP/3 requests now log the host header correctly, ensuring visibility into the host name of the server that handled the request.

TLS

  • OCSP stapling ECDSA issuer fix - when using ECDSA certificates for OCSP stapling, the issuer OID was not being correctly extracted from the certificate, leading to incorrect validation. This has been fixed to ensure the issuer OID is extracted correctly and used for OCSP validation.
  • TLS certificate provider inheritance fix - When using TLS certificates provided by a parent configuration, the certificate provider was incorrectly inherited, leading to errors when attempting to use these certificates in child configurations. This has been fixed to ensure that the certificate provider is correctly inherited and available for use in all child configurations.

HTTP server core

  • Error configuration routing fix - error configuration routing were resolved with a wrong configuration, when using a wildcard hostname in the configuration, even when no error configuration is set. This has been fixed to ensure wildcard hostnames are correctly handled.

Server startup

  • Critical Unix daemon initialization failure fix - when initializing as a Unix daemon, the forked process would exit due to logging re-initialization issues. This has been fixed to ensure that the parent process continues running even in such cases. (GitHub issue)

Don't miss a new ferron release

NewReleases is sending notifications on new releases.