xin

Configuration compatibility

xin reads the configuration language you already use. This page is the honest edge of that claim: what runs, what differs, and what will stop the server from starting.

Do not read this page to find out whether your config works. Run it instead — the answer is specific to your file and takes one command:

xind -t -c /etc/nginx/nginx.conf

Three outcomes, no fourth

OutcomeWhat it means
Runs xin reproduces the behaviour, including the parts of it that surprise people.
Runs, stated Behaviour differs in a known, catalogued way. Reported at load with file and line; the server still starts.
Refuses xin cannot honour the directive, so it does not start. The error names the file, the line and the reason.

Nothing is accepted, ignored and left unmentioned. A directive that would quietly do nothing is a startup failure instead — you find it in staging, not in an incident review.

Supported

AreaDirectives
Core structurehttp, server, location, upstream, include (with globs), default_type, worker_processes, worker_connections
Request routinglisten (addr, port, ssl, default_server, reuseport, backlog), server_name (exact, wildcard, regex) with nginx's matching order, location with nginx's precedence rules
Contentroot, alias, index, try_files, autoindex, error_page, return, rewrite, set, break, if (subset)
Static servingConditional requests, byte ranges including multipart, sendfile, if_modified_since, expires
Proxyingproxy_pass over http:// and https://, proxy_set_header, proxy_http_version, the proxy_ssl_* set with certificate pinning, proxy_read/connect/send_timeout, proxy_next_upstream, proxy_buffering, proxy_request_buffering, proxy_limit_rate, proxy_intercept_errors, proxy_ignore_headers, proxy_cookie_path/domain/flags
Upstreamsupstream blocks with server, weight, max_fails, fail_timeout, backup, down; keepalive; least_conn, ip_hash, hash, random [two]; passive health checks
TLSssl_certificate, ssl_certificate_key, ssl_protocols, ssl_ciphers, SNI, dual certificates, ALPN; HTTP/1.1 and HTTP/2
Filters & varsgzip with gzip_types/min_length/comp_level, map, geo, split_clients, real_ip, sub_filter
Access controlallow, deny, auth_basic, auth_basic_user_file, auth_request, satisfy, limit_except, valid_referers, secure_link
Limitslimit_req + limit_req_zone, limit_conn + limit_conn_zone + limit_conn_status, limit_rate, limit_rate_after, client_max_body_size, client_body/header_timeout, keepalive_timeout, keepalive_requests
Loggingaccess_log, error_log, log_format with the full variable set
Otheradd_header, mirror, X-Accel-Redirect, proxy_cache (in memory)

Refused at load

Each of these is a named startup error, never a silent skip. A build without a feature says so at startup rather than failing at request time.

Not supportedWhy
mail and stream modulesOut of scope. xin is an HTTP server; a TCP/UDP proxy is a different product.
uwsgi and SCGINot implemented. FastCGI is.
SSINot implemented.
Lua and njs scriptingNot implemented, and not planned.
Third-party C modulesThere is no module ABI, and there will not be one — that is the point of a single memory-safe binary.
fastcgi_cache, fastcgi_next_upstreamThe rest of FastCGI works; these two are refused rather than silently ignored.
proxy_store, proxy_store_accessThere is no filesystem-backed passthrough cache to write to, so a config relying on it would start and silently populate nothing.
ssl_ciphers OpenSSL group tokens (HIGH, MEDIUM…)A cipher policy that is approximated is a config that lies. Name the suites explicitly and it loads.

Compatibility means the bugs too

Where the documented behaviour and the actual behaviour of nginx disagree, xin follows the actual behaviour, because that is what your config was written against. Some examples that surprise people:

  • if_modified_since defaults to exact: a request date newer than the file gets the whole entity, not a 304. Implementing the intuitive comparison would serve a stale body.
  • location selection is not first-match-wins: = beats ^~ beats regexes-in-order beats longest prefix, independent of the order you wrote them in.
  • gzip on compresses exactly 200, 403 and 404 — not 201, not 301, not your 500 page.
  • proxy_ssl_verify defaults to off, so proxy_pass https://… is encrypted but unauthenticated unless you asked for verification.

One place xin deliberately follows intent instead: error_log off;. There is no off keyword for error_log — nginx treats it as a filename and creates a file called off. xin writes nothing and creates no such file.