Skip to content

Env-var reference

Every NESTRS_* environment variable, by namespace — the dual-path rule means each one also has a pinned-struct field.

Every framework module reads its config from a namespaced env prefix and from a pinned struct — the framework-wide dual-path rule (Configuration). The variable name is NESTRS_<NAMESPACE>__<KEY> (double underscore between namespace and key). This page lists the variables; each maps one-to-one to a field on the module’s config struct, so anything here is also settable in code — and, because the override is per field, setting one here works even when the app pins its neighbours in module.rs.

NESTRS is the default prefix. An app that declared its own (Your own prefix) reads every name below with that prefix instead — ACME_HTTP__PORT, ACME_LOG — and the NESTRS_ spellings resolve nothing.

The namespace is the path of the crate that parses it — never chosen. It is the same stem the config type is named from: the crate’s word, then the binding folder’s when the config sits in one, joined by __. HttpConfig reads NESTRS_HTTP__*; SeaOrmConfig reads NESTRS_SEAORM__*; RedisWorkerConfig (in nest-rs-redis’s worker/ folder) reads NESTRS_REDIS__WORKER__*; SocialGithubConfig reads NESTRS_SOCIAL__GITHUB__*. So from any variable on this page you can name the type and the file that parse it, and from any <X>Module::for_root in a composition root you can name its variables: the vendor is in the variable exactly when it is in the type. That is also why there is no NESTRS_DATABASE__URL — the universal convention, but a word that names neither the crate nor the type, so a reader could not find the code from it.

The baseline console logger is part of nest-rs-core — no module to import, no config struct. It reads two process-level variables:

KeyMeaning
NESTRS_LOGtracing filter (e.g. info, debug,hyper=warn); falls back to RUST_LOG, default info
NESTRS_LOG_FORMATjson (the release default) or text (the dev default)
NESTRS_LOG_SOURCE_LOCATIONappend the emitting file:line to each event — default false

An app that installs its own subscriber first (e.g. through OpenTelemetry) keeps it — the baseline logger only activates when none is set. The same three variables drive the console layer of the OpenTelemetry subscriber too, so log config survives adopting or dropping the observability stack.

KeyMeaning
HOSTlisten address (default 0.0.0.0)
PORTlisten port
GLOBAL_PREFIXpath prefix for every route (unset ⇒ none)
MAX_BODY_BYTESrequest body cap
REQUEST_TIMEOUT_SECSper-request timeout — default 30, 0 ⇒ no timeout. An overrun answers 503 with a Retry-After, not 504: this transport is the origin, not a gateway
FAIL_SECURE_STRICTfail boot (vs warn) on an unguarded self-mount under global guards — default true
SECURITY_HEADERSmaster switch for the secure-by-default response headers
HSTS · FRAME_OPTIONS · CONTENT_TYPE_OPTIONS · SERVER_HEADERindividual security-header controls
REFERRER_POLICY · CROSS_ORIGIN_OPENER_POLICY · CROSS_ORIGIN_RESOURCE_POLICYthe rest of the default-on set — strict-origin-when-cross-origin, same-origin, same-origin; an empty value drops one
CONTENT_SECURITY_POLICY · CROSS_ORIGIN_EMBEDDER_POLICY · PERMISSIONS_POLICYsettable, off by default — each governs a document whose sources the framework cannot speak for; see HTTP configuration
TLS_CERT / TLS_KEYPEM cert + key for HTTPS (inline); TLS_CERT_FILE / TLS_KEY_FILE read from a path instead. Unset ⇒ plain HTTP
TLS_RELOAD_SECShow often a file-sourced pair is re-read, so a renewal swaps in without a restart — default 60, 0 disables
VERSIONINGhow a caller selects an API version — uri (default), header, media_type
VERSION_HEADERthe header the header strategy reads — default X-API-Version
DEFAULT_VERSIONthe version served to a caller that states none; unset ⇒ the unversioned routes
CORS_ORIGINScomma-separated allowed origins; unset ⇒ no CORS layer
CORS_METHODScomma-separated allowed request methods
CORS_HEADERScomma-separated allowed request headers
CORS_EXPOSEDcomma-separated response headers exposed to the browser
CORS_CREDENTIALSallow credentialed requests — default false
CORS_MAX_AGEpreflight cache lifetime in seconds
COMPRESSIONnegotiate response compression from Accept-Encoding — default false (leave it to the proxy unless the app terminates responses)
SSE_MAX_CONNECTION_SECShow long an #[sse] stream may stay open before the server ends it and the client reconnects — default 14400 (4 h), 0 ⇒ unlimited. A security control: the stream authenticates once, at the request
SSE_KEEP_ALIVE_SECSkeep-alive comment interval on an #[sse] stream, so an idle feed is not dropped by an intermediary — default 15, 0 ⇒ none sent
ACCESS_LOGemit one access-log event per request on nest_rs::operation — default true. Owned by the HTTP transport, so it needs no observability crate; trace_id joins the line only when one is mounted
TRUSTED_PROXIEScomma-separated reverse-proxy IPs whose Forwarded (RFC 7239) / X-Forwarded-For / X-Real-IP / traceparent / X-Request-Id are believed. Empty (the default) ⇒ none is read, every caller is its transport peer, and every inbound trace is restarted. Shared by ClientIp, the throttler and the trace context; an unparseable entry aborts the boot

The one pool every SeaORM binding shares, opened by SeaOrmModule::for_root. The engine is in the URL’s scheme (postgres://, mysql://, sqlite://) — sea-orm picks it, the variable does not change.

KeyMeaning
URLdatabase connection string
MAX_CONNECTIONSpool maximum connections (unset ⇒ SeaORM default)
MIN_CONNECTIONSpool minimum connections (unset ⇒ SeaORM default)
CONNECT_TIMEOUT_SECSconnection-acquire timeout in seconds
SQLX_LOGGINGlog SQL statements
OBSERVE_SERIALIZATION_CONFLICTStag commit-time serialization conflicts at warn

The one Redis connection every Redis binding shares — the queue producer, the worker and the rate-limit store — opened by RedisModule::for_root. One connection, one variable: a throttler-only app sets the same URL a queue app does.

KeyMeaning
URLRedis connection string
CONNECT_TIMEOUT_SECSboot budget for reaching Redis before failing with a named error; defaults to 10, and 0 is rejected. Each attempt warns on nest_rs::redis, so an unreachable backend is a bounded boot failure rather than a process that never becomes healthy and never crashes

The consumer binding’s own settings, resolved by RedisWorkerModule::for_root. Two segments because the config sits in the crate’s worker/ folder: the crate’s word, then the binding’s — exactly the stem RedisWorkerConfig is named from.

KeyMeaning
SHUTDOWN_TIMEOUT_SECShow long the worker waits for in-flight jobs after a shutdown signal; defaults to 30
KeyMeaning
ENDPOINTS3 endpoint (empty ⇒ real AWS S3)
REGIONregion
ACCESS_KEY / SECRET_KEYstatic credentials
BUCKETtarget bucket
FORCE_PATH_STYLEpath-style vs virtual-hosted addressing
ALLOW_HTTPreach the endpoint over plain http:// — default true in dev/test, false in staging/production so credentials never travel unencrypted by omission. false + an http:// ENDPOINT fails boot, naming the variable; the refusal covers presigned URLs, which are signed locally and would otherwise ship a working plaintext URL
KeyMeaning
SERVICE_NAMEservice name; overrides the name passed to OpenTelemetry::init
OTLP_ENDPOINTcollector endpoint (unset ⇒ no export)
SAMPLE_RATIOtrace sampling ratio, 0.01.0 (default 1.0)
METRIC_INTERVAL_SECSmetric export period (default 60; 0 keeps the default). Traces and logs export immediately — metrics wait for this flush
SERVICE_VERSION · SERVICE_ENVIRONMENT · SERVICE_INSTANCE_IDresource attributes

The console layer reads the NESTRS_LOG* family above — there are no OTel-specific log variables.

JWT key material and validation for nest-rs-authn. A resource server sets only the verification side (SECRET or PUBLIC_KEY); the issuer app also sets the signing side.

KeyMeaning
SECRETHS256 shared secret (≥ 32 bytes) — signs and verifies
PRIVATE_KEYEdDSA private key (PEM) — issuer only, to sign
PUBLIC_KEYEdDSA public key (PEM) — to verify
ISSUERexpected iss claim (unset ⇒ no issuer check)
AUDIENCEexpected aud claim. Set ⇒ the claim is mandatory and must name this app. Unset does not disable the check: a token carrying an aud this app is not named in is refused either way (RFC 7519 §4.1.3)
ALLOW_ANY_AUDIENCEopt out of that clause and accept a token minted for another service (default false). Refused beside AUDIENCE, and reported at warn once per boot
LEEWAY_SECSclock-skew leeway in seconds (default 30)
EXPIRES_IN_SECSminted-token lifetime in seconds (default 3600)
EXPLICIT_TYPINGrequire the JWT typ header to name the token’s type (default true)

The login flow’s provider endpoints, read by OAuthClientConfig in nest-rs-oauth-client. Every field is required, so an unconfigured app fails boot naming the field:

KeyMeaning
CLIENT_ID / CLIENT_SECRETthe registered OAuth2 client credentials
AUTH_URLprovider authorization endpoint (where the user consents)
TOKEN_URLprovider token endpoint (code → tokens)
REDIRECT_URLthis app’s callback the provider returns to
USERINFO_URLprovider endpoint the profile is fetched from
SCOPEScomma-separated scopes requested at authorization (empty by default)

oauth_resourceNESTRS_OAUTH_RESOURCE__*

Section titled “oauth_resource — NESTRS_OAUTH_RESOURCE__*”

OAuthResourceModule is what turns the app into a conformant OAuth 2.1 resource server (RFC 9728) and what an MCP server needs. Importing it makes NESTRS_AUTHN__AUDIENCE mandatory: the boot fails without it rather than leaving the app unable to say which tokens are its own. (A token minted for another named audience is refused with or without the module — that is RFC 7519 §4.1.3. What the module adds is that a token carrying no aud at all is refused too.)

KeyMeaning
RESOURCEthis deployment’s canonical resource URI — the value tokens must carry as aud. Required under the module
AUTHORIZATION_SERVERScomma-separated issuer identifiers allowed to mint tokens for it. At least one required
SCOPES_SUPPORTEDcomma-separated minimal scope set, advertised in the metadata document and the WWW-Authenticate challenge
BEARER_METHODS_SUPPORTEDhow a token may be presented — defaults to header, the only form accepted
RESOURCE_NAMEhuman-readable name for a consent screen
RESOURCE_DOCUMENTATIONURL of developer documentation for this resource
RESOURCE_POLICY_URIURL of this resource’s privacy policy, advertised in the metadata document
RESOURCE_TOS_URIURL of this resource’s terms of service, advertised in the metadata document
KeyMeaning
ALLOWED_HOSTScomma-separated Host authorities accepted (anti-DNS-rebinding). Defaults to loopback, so a public deployment must name itself; an empty list disables the check and is reported at warn
LEGACY_SESSION_MODEkeep sessions alive for protocol revisions older than 2026-07-28 — default true
JSON_RESPONSEanswer simple operations with application/json instead of an SSE stream — default false
SSE_KEEP_ALIVE_SECSSSE keep-alive ping interval (0 ⇒ none) — default 15
SSE_RETRY_SECSretry: interval advertised on SSE priming events (0 ⇒ none) — default 3
MAX_REQUEST_BODY_BYTEScap on a single POST body, enforced while streaming — default 4 MiB
STATELESS_PROTOCOL_METADATA_REQUIREDrequire per-request protocol metadata on stateless POSTs (SEP-2243) — default false

One sub-namespace per provider (GITHUB, GOOGLE). Credentials decide the provider’s fate: complete ⇒ active, absent ⇒ inert with a boot warn, partial ⇒ the boot fails naming the provider.

KeyMeaning
CLIENT_ID / CLIENT_SECRETthe provider’s OAuth app credentials
REDIRECT_URLthe registered callback this app is returned to
SCOPEScomma-separated scopes; each provider has a sensible default when unset

The endpoint URLs are provider constants, not config — see Social login.

These read their own NESTRS_<NAMESPACE>__* keys. The rule is uniform: the struct’s field name uppercased is the key. Two namespaces are not spelled the way their section is, so the page is named rather than left to a search:

NamespaceDocumented on
graphqlGraphQL configuration
openapiOpenAPI
healthHealth
throttlerRate limiting
wsWebSockets
issuerthe demo feature library — the Publish workspace

Values resolve highest-first: real env > pinned in module.rs > .env.<NESTRS_ENV>.local > .env.local > .env.<NESTRS_ENV> > .env. See the env cascade for the files and the dual-path rule for where a pinned value sits.