Skip to main content
Version: v1.24.0

Configuration reference

This page lists every configuration key the framework recognizes, with its default value and lifecycle. For how configuration is loaded and merged — file formats, the multi-file loader, list operators, module config — see Concepts → Configuration.

How to read this page

Precedence. Values are resolved lowest-to-highest:

struct defaults < config file(s) < NUCLEUS_* env vars

Environment variables. Every key maps to a NUCLEUS_-prefixed variable. Flat keys use one underscore (portNUCLEUS_PORT); nested keys join segments with a double underscore (databases.<alias>.urlNUCLEUS_DATABASES__<ALIAS>__URL).

Lifecycle.

TagMeaning
stableKey name and semantics are contract surfaces on the v1.x line.
transitionalSupported, but semantics may still refine before freezing.
experimentalNo compatibility guarantee yet.
removedNo longer accepted; the notes name the replacement.

To see the value every key actually resolves to in a running deployment — and which file or variable set it — use nucleus config print --effective (CLI overview).

Server

KeyDefaultLifecycleNotes
host0.0.0.0stableBind host.
port8080stableBind port.
read_timeout30sstableHTTP read timeout.
write_timeout60sstableHTTP write timeout.
idle_timeout120sstableHTTP idle timeout.
request_timeout30stransitionalPer-request handler deadline: past it the client receives a 503 and the handler's context is cancelled. 0 keeps the default; a negative value (-1s) disables the timeout on every route. Streaming routes are better exempted with timeout_exempt_paths. Before this key existed the deadline silently reused read_timeout.
timeout_exempt_paths[][]transitionalURL path prefixes served without the request timeout and with the raw response writer (Flush/Hijack work): server-sent events, long polls, large downloads. Requests whose Accept header asks for text/event-stream are exempt without listing them.
tls_cert_file""transitionalPEM certificate (chain) file. When both tls_cert_file and tls_key_file are set, App.Run serves HTTPS directly (ListenAndServeTLS); when either is empty the server speaks plain HTTP (terminate TLS at a reverse proxy instead).
tls_key_file""transitionalPEM private-key file paired with tls_cert_file.

Database

KeyDefaultLifecycleNotes
database_defaultdefaultstablePrimary DB alias used by app.DB.
databases.<alias>.urldatabases.default.url=sqlite://nucleus.dbstable + experimentalStable schemes: sqlite://, postgres://, postgresql://, mysql://; exploratory schemes: sqlserver:///mssql://, oracle://.
databases.<alias>.max_open25stablePer-alias pool max open conns (inherits primary if omitted).
databases.<alias>.max_idle5stablePer-alias pool max idle conns (inherits primary if omitted).
databases.<alias>.max_lifetime5mstablePer-alias conn max lifetime (inherits primary if omitted).

MultiSite and MultiTenant

KeyDefaultLifecycleNotes
multisite.enabledfalsestableEnable host-based site resolution.
multisite.default_sitedefaultstableFallback site when host does not match configured patterns.
multisite.sites.<site>.hosts[][]stableExact host or wildcard (*.example.com) patterns per site.
multisite.sites.<site>.databasedatabase_defaultstableDefault DB alias for the site.
multisite.sites.<site>.tenant_database_alias_template""stableOptional per-site tenant DB alias template (tenant_%s or {tenant}).
multitenant.enabledfalsestableEnable tenant resolution.
multitenant.resolversubdomainstablesubdomain or header.
multitenant.headerX-Tenant-IDstableHeader used when resolver is header.
multitenant.default_tenant""stableOptional fallback tenant id.
multitenant.require_isolated_dbtruestableSecurity-by-default guard: rejects shared DB alias routing across tenants.
multitenant.require_tenant_storagefalsestableStorage operations with no tenant in context fail (storage.ErrNoTenantInContext) instead of silently using the shared unprefixed key space. Off: the first degradation logs one WARN.
multitenant.database_alias_templatetenant_%sstableGlobal tenant DB alias template (%s or {tenant}).
multitenant.tenants.<tenant>.site""stableOptional site binding for a tenant mapping.
multitenant.tenants.<tenant>.database""stableExplicit tenant DB alias mapping.

Redis and Sessions

KeyDefaultLifecycleNotes
redis_url""stableOptional Redis endpoint for queue/session features.
session_lifetime72hstableServer-side session lifetime.
session_storememorystableSupported values: memory, sql, redis.
session_redis_url""stableRedis override for session backend.
session_tablenucleus_sessionsstableSQL session table name.
session_cookie_namesessionstableSession cookie name.
session_cookie_domain""stableSession cookie domain.
session_cookie_path/stableSession cookie path.
session_cookie_securetruestableSession cookie Secure attribute. Secure-by-default — the cookie refuses to ride over plain HTTP. Local development over http:// must opt out with session_cookie_secure: false. Mirrors the CSRF cookie posture.
session_cookie_samesitelaxstableSameSite policy string.
session_idle_timeout0stableOptional idle timeout override.
session_redis_prefixnucleus:sessions:stableSession Redis key prefix.
session_memcached_servers[][]transitionalhost:port list for session_store: memcached.

Auth

KeyDefaultLifecycleNotes
jwt_secret""stableSingle-secret HS256 used as legacy fallback when jwt_keys is empty. Must be at least 32 bytes when set — a shorter secret is a boot error (enforced since v1.2.0; generate one with openssl rand -base64 32). Tokens carry no kid header. When jwt_keys[] is non-empty this key is ignored. See jwt_keys[] for the production multi-key path.
jwt_expiry24hstableJWT lifetime default.
jwt_issuer""stableIssuer claim (iss) stamped into every token minted by App.JWT. Used by both single-secret and multi-key managers.
jwt_audience""transitionalAudience stamped into every token the app mints and required of every token it accepts; empty leaves aud unchecked. The issuer is always verified.
jwt_keys[][]stableOrdered keyset consumed by App.New to build a *auth.JWTManager via auth.NewJWTManagerFromKeys. Each entry is a JWTKeySpec sub-object — see table below. When non-empty, jwt_secret is ignored.
jwt_current_kid""stablekid value that identifies the active signing key within jwt_keys[]. Must match one entry's kid. New tokens are signed with this key; all keyset keys remain valid for validation.

jwt_keys[] entry fields (JWTKeySpec)

Exactly one of secret_env / pem_path / pem_env must be set per entry — key material is never read from tracked config files:

FieldTypeNotes
kidstringUnique key identifier stamped in token kid header. Required.
algorithmstringHS256, RS256, or ES256. Required.
secret_envstringResolver reference to the HMAC secret (HS256 only). See reference forms below.
pem_pathstringFilesystem path to a PEM-encoded private key (RS256: RSA, PKCS#1/PKCS#8; ES256: ECDSA P-256, SEC1/PKCS#8). Rejects PEM with trailing content.
pem_envstringResolver reference to PEM bytes (RS256 / ES256). See reference forms below.

Reference forms accepted by secret_env and pem_env (plain names read the environment; the aws-sm: scheme reads AWS Secrets Manager via the standard credential chain):

ReferenceResolved from
MY_VARenvironment variable MY_VAR (historical behaviour)
env:MY_VARenvironment variable MY_VAR (explicit form)
aws-sm:<secret-id>AWS Secrets Manager secret <secret-id>
aws-sm:<secret-id>#<json-key>one string field of a JSON-object AWS secret

RBAC

KeyDefaultLifecycleNotes
rbac_policy_file""stablePath to Casbin RBAC CSV policy file. Feeds the core authz enforcer (pkg/authz.Enforcer). CSV rows require a 4th column (allow / deny) — the model uses deny-override semantics. Programmatic callers use Enforcer.AddPolicy (auto-stamps allow) and Enforcer.Deny. Auto-discovered at rbac_policy.csv, config/rbac_policy.csv, or rbac/rbac_policy.csv when the key is empty.
admin_rbac_policy_file""removedRemoved in v0.12.0. Use rbac_policy_file

Admin (removed — moved to the orbit module)

KeyFormer defaultLifecycleMigration
admin_prefix/adminremovedUse modules.orbit.prefix (see orbit module docs).
admin_titleNucleus AdminremovedUse modules.orbit.title.
admin_auth_database""removedUse modules.orbit.auth_database.
admin_bootstrap_username""removedUse modules.orbit.bootstrap_username.
admin_bootstrap_email""removedUse modules.orbit.bootstrap_email.
admin_bootstrap_password""removedUse modules.orbit.bootstrap_password.
admin_live_exclude_patterns[][/admin]removedUse modules.orbit.live_exclude_patterns.
admin_cluster_enabledfalseremovedUse modules.orbit.cluster_enabled.
admin_cluster_redis_url""removedUse modules.orbit.cluster_redis_url.
admin_cluster_channelnucleus:admin:live:v1removedUse modules.orbit.cluster_channel.
admin_cluster_node_id""removedUse modules.orbit.cluster_node_id.
admin_cluster_token""removedUse modules.orbit.cluster_token.
admin_trace_url_template""removedUse modules.orbit.trace_url_template.

Mail

KeyDefaultLifecycleNotes
mail_drivernoopstableBuilt-in and plugin-backed provider selection.
mail_fromnoreply@localhoststableDefault sender.
smtp_host""stableSMTP host.
smtp_port587stableSMTP port.
smtp_user""stableSMTP user.
smtp_pass""stableSMTP password.
mail_circuit_breaker.enabledtruestableWrap mail.Sender.Send with a pkg/circuit breaker. noop driver is never wrapped. Healthy (SMTP HELO probe) bypasses the breaker so /healthz observes recovery.
mail_circuit_breaker.failure_threshold5stableConsecutive Send failures required to trip the breaker open.
mail_circuit_breaker.cooldown30sstableTime the breaker stays open before admitting half-open probes.
mail_circuit_breaker.half_open_max_concurrent1stableIn-flight probe budget while half-open.

Module Jobs and Webhooks

KeyDefaultLifecycleNotes
jobs_providermemorystablepkg/tasks provider that executes module jobs: memory (in-process scheduler + workers; pending jobs are lost on restart) or asynq (Redis-backed, durable; requires jobs_redis_url). Added in v1.4.0.
jobs_redis_url""stableRedis connection URL for the asynq jobs provider (e.g. redis://localhost:6379/0). Required when jobs_provider: asynq — validated at boot; ignored by memory. Added in v1.4.0.
jobs_concurrency4stableNumber of concurrent job workers. 0 uses the provider default. Added in v1.4.0.
jobs_scheduler_locktruestableLeader election for the asynq scheduler over a Redis lock (SET NX + TTL): with multiple replicas exactly one process ticks the cron entries; workers run on every replica either way. false opts out and the boot log WARNs that each replica fires every job. Ignored by the memory provider.
webhooks_prefix/webhooksstableURL prefix under which module webhook routes mount: <prefix>/<module-name><path>. With csrf_enabled: true the framework exempts this prefix from CSRF automatically — webhooks authenticate by HMAC signature (X-Nucleus-Signature), not by CSRF token. Added in v1.4.0.

Transactional Outbox (outbox.*)

KeyDefaultLifecycleNotes
outbox.enabledfalsetransitionalEnables the outbox: the table lives on the default database and the leasing dispatcher starts with the app.
outbox.table_namenucleus_outboxtransitionalName of the outbox table.
outbox.lease_duration30stransitionalHow long a claimed message stays leased to one dispatcher instance before another may claim it.
outbox.max_retries5transitionalDelivery attempts before a message is marked failed.
outbox.retry_backoff1stransitionalBase delay for the exponential retry backoff.
outbox.lease_owner`` (per-instance)transitionalIdentifies this instance in lease rows. Empty derives nucleus-<hostname>-<pid>; set explicitly for a stable identity (e.g. a k8s pod name). Before v1.8.2 every process shared the literal nucleus-app.
outbox.missing_route_policyerrortransitionalWhat a dispatcher does with a leased message whose topic has no registered bridge: error fails it; ignore releases it for the instance that can deliver it (heterogeneous fleets). Invalid values fail startup.
outbox.bridges.<n>.nametransitionalBridge instance name (required; also the routing target name). Bridge entries are configured in files only: the NUCLEUS_* double-underscore mapping has no list-index syntax, so per-entry env overrides do not apply.
outbox.bridges.<n>.typetransitionalBridge type. webhook is the delivering implementation; kafka is disabled and fails boot.
outbox.bridges.<n>.config.urltransitionalWebhook bridge: delivery endpoint URL (required).
outbox.bridges.<n>.config.pattern*transitionalWebhook bridge: topic pattern routed to this bridge (e.g. orders.*).
outbox.bridges.<n>.config.headerstransitionalWebhook bridge: extra HTTP headers sent on every delivery (e.g. an Authorization value). The contract headers X-Outbox-Payload-Encoding and X-Nucleus-Signature cannot be overridden.
outbox.bridges.<n>.config.secret""transitionalWebhook bridge: HMAC-SHA256 signing secret. When set, every delivery carries X-Nucleus-Signature: sha256=<hex> over the exact body — the same scheme module webhooks verify, so consumers share one verifier. Empty: deliveries are unsigned and the boot log WARNs once per bridge. Added after v1.4.0.
outbox.bridges.<n>.config.payload_encodingbase64transitionalWebhook bridge: wire shape of the body's payload field. base64 (default) is the classic shape every release up to v1.4.0 emits (the payload as a base64 JSON string); json opts in to embedding the payload's JSON document verbatim. Every delivery declares its actual shape in X-Outbox-Payload-Encoding, whatever the mode. Added after v1.4.0.

Observability and Security

KeyDefaultLifecycleNotes
log_levelinfostableLogger level selector.
log_formatjsonstablejson/text formatter contract.
log_redact_extra_keys[][]transitionalAdditional log attribute keys whose values the structured logger redacts, on top of the built-in denylist (observe.DefaultRedactedKeys). Case-insensitive. Use it for app-specific sensitive fields (ssn, card_number, …). There is intentionally no config key to disable redaction — redaction is on by default and turning it off requires an explicit code-level opt-out via observe.NewLoggerWithRedaction
otlp_endpoint""stableOptional OTLP-HTTP push endpoint for traces + metrics. Requires the exporters/otlp module (nucleus add otlp): the core keeps the OpenTelemetry SDK and links no exporter, so a non-empty endpoint without the module stops startup with the import to add. Coexists with metrics_path — when both are set, the MeterProvider feeds both readers.
metrics_path/metricsstableMount path for the Prometheus / OpenMetrics scrape endpoint. Empty string disables the endpoint. Requires the exporters/prometheus module (nucleus add prometheus); the core links no exporter. When the module is imported and the path is non-empty, App.New attaches a Prometheus reader to the OTel MeterProvider and serves it at this path with application/openmetrics-text content type. Without the module: a path you wrote yourself stops startup with the import to add, while the untouched default only logs at startup that metrics are not being served and the application boots with the path answering 404. The endpoint carries no authentication of its own: when enabled, restrict access at the network / reverse-proxy layer (allow-list your scraper) or mount your own guard middleware in front of it.
metrics_publictruestableWhether the metrics endpoint is seeded into the anonymous bootstrap allow-list. true (default, the historical behaviour) lets Prometheus scrape without credentials — pair it with network-layer restrictions. false keeps /metrics OUT of the allow-list, so the default-deny RBAC enforcer gates it like any user route: grant your scraper an explicit policy (e.g. p, metrics-scraper, /metrics, *) plus JWT auth, or use a reverse-proxy guard. Added in v1.3.0.
sql_driver_instrumentationfalsestableOpt-in driver-level SQL instrumentation. false (default): the observability live SQL feed shows only model.CRUD traffic and the database/sql driver is not wrapped — zero hot-path cost. true: the driver is wrapped so direct db.QueryContext/ExecContext statements that bypass CRUD (outbox dispatch, SQL session stores, migrations, raw SQL) also reach the feed. CRUD statements are not double-recorded (de-duplicated by a context marker). Adds a small per-direct-statement cost when enabled; the expensive sanitize+emit still runs only when a subscriber is attached. Added in v1.3.0.
rate_limit_requests0stableSustained rate budget (0 disables).
rate_limit_window1mstableRate limit refill window.
rate_limit_burst0stableBurst capacity over sustained budget.
rate_limit_by_routefalsestablePer-route token bucket partitioning.
rate_limit_by_rolefalsestablePer-role token bucket partitioning.
cors_origins[][] (empty)stableCORS allow-list. Empty (the default) DENIES cross-origin requests — no CORS headers are emitted. A non-empty list restricts CORS to exactly these origins; the historical allow-all is the explicit opt-in ["*"].
cors_allow_credentialsfalsestableEmit Access-Control-Allow-Credentials: true. Only honored when cors_origins is non-empty — the Fetch standard forbids credentials with the * wildcard.
csrf_enabledfalsestableMounts the router's CSRF middleware (router.WithCSRF): Sec-Fetch-Site origin verification with a double-submit token fallback. Opt-in because CSRF protection only applies to cookie/session-authenticated browser routes — a pure Bearer-token API does not need it. The mvc scaffold ships with true. Added in v1.3.0.
csrf_exempt_paths[][]stableURL path prefixes excluded from CSRF validation (Bearer-only subtrees such as /api/, signature-authenticated webhook receivers). Only meaningful with csrf_enabled: true.
csrf_insecure_cookiefalsestableDevelopment-only opt-out: disables the Secure attribute on the CSRF cookies so the double-submit flow works for plain-HTTP non-browser clients (Go cookiejar over http://127.0.0.1). Mirrors session_cookie_secure: false. Never enable in production.
trusted_proxies[][] (empty)stableUpstream proxy addresses (IPs or CIDRs) whose X-Forwarded-For / X-Real-IP headers the RealIP middleware honors. Empty (the default) IGNORES forwarding headers and uses the immediate peer (r.RemoteAddr) as the client IP, preventing header-spoofed rate-limit evasion and audit-log poisoning. Set to your load balancer / reverse-proxy ranges (e.g. ["10.0.0.0/8"]) when Nucleus runs behind one.
auth_backends[][] (empty)stableORDERED list of authentication backend names (registered with auth.RegisterBackend; the application's own user table appears here under the name given to WithUserProvider, local by default). Order is meaningful: [ldap, local] consults the directory first and falls through to the local table when the directory cannot be reached — a backend that is UNAVAILABLE is skipped, one that REJECTS ends the attempt. A name that is not registered fails at boot; a repeated name is rejected because the list is a chain, not a set. Empty means no chain is built.
storage.<provider>.*stableConfiguration subtree of a REGISTERED third-party storage provider (storage.RegisterProvider). The framework validates only that the section belongs to a registered name — a misspelled section is still an unknown key; the provider validates its own contents through storage.Config.BindProvider, where a key its struct does not declare is an error. Built-in providers use their typed sections (storage.s3.*, storage.local.*, …) instead.
auth.<backend>.*stableConfiguration subtree of a REGISTERED authentication backend (auth.RegisterBackend), keyed by the name used in auth_backends. Same rule as storage.<provider>.*: the framework validates only that the section belongs to a registered name — a misspelled section is still an unknown key — and the backend validates its own contents through auth.BackendConfig.Bind, where a key its struct does not declare is an error. A backend that needs no settings needs no section. A section whose backend is NOT listed in auth_backends is an ERROR: the chain is its only consumer, so it would boot clean and be read by nobody. Added in v1.15.0.
auth_federated[][] (empty)stableBrowser-redirect identity providers (OIDC, SAML). Each entry declares name (the INSTANCE: its URL segment, its auth.<name>.* subtree and its sign-in button), provider (the registered protocol type) and an optional display_name. Instance and type are separate fields because two identity providers of the same protocol — a corporate tenant and a partner one — is an ordinary configuration. Independent of auth_backends: a federated flow has no credentials to hand to a chain. A provider nobody registered fails at boot, naming what is registered; two entries sharing a name fail, because they would share a callback URL. Added in v1.17.0.
public_base_url"" (empty)stableThe address the BROWSER reaches this application at, without a trailing slash. REQUIRED when auth_federated is non-empty: the callback URL an operator registers with their identity provider is derived from it, and behind a reverse proxy or in a container it is not the address the process binds. The resolved callback URLs are logged at startup. Added in v1.17.0.
http_interceptors[][] (empty)stableORDERED list of registered request interceptors (interceptor.Register), outermost first: the first name sees the request first and the response last. Order is the behaviour, not a detail — authentication before rate limiting and rate limiting before authentication are different systems. A name that is not registered fails at boot naming what is, a factory that errors fails boot, and a repeated name is rejected. Interceptors mount INSIDE the framework's own middleware, after the request ID, the session and the observability hook. Added in v1.17.0.
interceptors.<name>.*stableConfiguration subtree of a REGISTERED request interceptor, keyed by the name used in http_interceptors — the same pairing as auth_backends with auth.<backend>.*: the list orders, the subtree configures. The framework validates only that the section belongs to a registered name; the interceptor validates its own contents through interceptor.Config.Bind, where a key its struct does not declare is an error. Added in v1.17.0.

Localization, Static, Storage, Environment

KeyDefaultLifecycleNotes
default_localeenstableDefault i18n locale. Read by the i18n CLI pair and by the runtime: when compiled catalogs are loaded, a request whose Accept-Language matches no catalog locale falls back to this locale (see pkg/i18n).
locales_pathlocales/stableLocale catalog path. makemessages/compilemessages write catalogs here; at startup the app loads any compiled JSON bundles under it and, when at least one locale exists, mounts the Accept-Language negotiation middleware.
static_prefix/static/stableStatic route prefix.
templates_dirinternal/web/templatesstableRoot of the HTML template tree. Loaded recursively at startup (since v1.8.2): every .html registers under its path relative to this dir with forward slashes (fieldservice/index.html); root files keep their flat name (base.html); {{define}} blocks register under their declared names. The startup log reports templates loaded with the count; a present-but-empty dir logs a WARN.
static_rootstatic/stableStatic collection target root.
storage_driverremovedRemoved in v0.12.0. Use storage.provider
storage_pathremovedRemoved in v0.12.0. Use storage.local.path
envdevelopmentstableEnvironment mode (development/production).
debugfalsestableDebug feature toggles.
profile`` (none)stableNamed preset applied over the loaded config. dev swaps every backing-service selection for its no-dependency counterpart — SQLite database (extra aliases dropped; an already-SQLite URL is kept), in-memory sessions and jobs, local filesystem storage, no-op mailer — so the same file boots with zero external services. Unknown values fail config load.

Unified Storage (storage.*)

KeyDefaultLifecycleNotes
storage.providerlocalstableBackend: local (built in), or s3, gcs, azure — each a module of its own (`providers/storage-s3
storage.defaultprivatestableDefault object visibility (private/public).
storage.public_url_base""stableBase URL for public objects (CDN or provider).
storage.public_paths{}stableMaps URL paths to storage key prefixes.
storage.s3.endpoint""stableCustom S3 endpoint (MinIO, R2). Empty = AWS.
storage.s3.bucket""stablePrimary S3 bucket name.
storage.s3.region""stableAWS region.
storage.s3.access_key_id""stableAWS access key. Accepts a plain string (literal value) or the credential-source shape: value / env_var / file / secret_manager sub-keys.
storage.s3.secret_access_key""stableAWS secret key. Plain string or credential-source shape (value/env_var/file/secret_manager).
storage.s3.session_token""stableAWS session token for temporary credentials. Plain string or credential-source shape.
storage.s3.use_path_stylefalsestablePath-style URLs (required for MinIO).
storage.s3.public_bucket""stableDedicated public bucket name.
storage.s3.create_bucket_if_missingfalsestableProvision the bucket(s) at startup when missing. Opt-in; without it a missing bucket fails app.New loudly. Was advertised by the startup error but rejected by the loader until v1.8.1.
storage.gcs.bucket""stablePrimary GCS bucket.
storage.gcs.public_bucket""stableDedicated public GCS bucket.
storage.gcs.credentials""stableGCS service-account credentials. Plain string or credential-source shape (typically file: for the mounted SA JSON); empty = Application Default Credentials.
storage.azure.account_name""stableAzure storage account name. Plain string or credential-source shape.
storage.azure.account_key""stableAzure storage account key. Plain string or credential-source shape.
storage.azure.container""stablePrimary container name.
storage.azure.public_container""stablePublic container name.
storage.local.pathstorage/stableLocal filesystem root (dev only).
storage.cleanup.enabledfalsestableEnable automatic temp file cleanup.
storage.cleanup.interval1hstableCleanup run frequency.
storage.cleanup.prefix_tmp/stablePrefix for temporary objects.
storage.cleanup.max_age24hstableMax age before temp files are purged.
storage.circuit_breaker.enabledtruestableWrap remote provider ops (Put/Get/Delete/Exists/List/Copy/SignedURL) with a pkg/circuit breaker. Local provider is never wrapped. PublicURL is pass-through. ErrNotFound is not counted as a failure.
storage.circuit_breaker.failure_threshold5stableConsecutive op failures required to trip the breaker open.
storage.circuit_breaker.cooldown30sstableTime the breaker stays open before admitting half-open probes.
storage.circuit_breaker.half_open_max_concurrent1stableIn-flight probe budget while half-open.

Module configuration (modules.*)

The modules.<name>.* namespace is reserved for mounted modules. Each module owns its own schema, declared as struct tags on its typed config — the framework does not validate those keys against the tables above. Two practical limits: the NUCLEUS_MODULES__* env-var pattern is not applied (module config comes from files or code), and nucleus config print --effective excludes modules.* values (module schemas are open-ended and may carry secrets). See Concepts → Configuration → Module-specific configuration for the full authoring guide.