Skip to main content

Configuration keys

Every key the Egret server reads, grouped by section, with its environment variable, default and meaning. The source of truth is the Config struct in crates/egret-config/src/lib.rs; the tables below follow its order. For how the layers combine and for worked examples, see Configuration.

How a key becomes an environment variable​

Configuration is layered: built-in defaults, then egret.toml in the working directory, then environment variables. The environment wins.

  • The environment variable for [section] key is EGRET_<SECTION>__<KEY> in upper case, with two underscores between the section and the key. A key inside a sub-table adds another pair: [workflow.storage] max_file_bytes is EGRET_WORKFLOW__STORAGE__MAX_FILE_BYTES. A section whose name contains an underscore keeps it: [data_api] public_url is EGRET_DATA_API__PUBLIC_URL, and [rate_limit] login_max_attempts is EGRET_RATE_LIMIT__LOGIN_MAX_ATTEMPTS.
  • Lists and tables take TOML syntax in the variable: EGRET_OIDC__SCOPES='["openid","email","profile"]'.
  • Keys marked required in the Default column have an empty default and a boot-time check; the server refuses to start without them (see Startup checks).
  • A key the server does not know is silently ignored at the top level and in most sections. A typo in a variable name therefore leaves the default in place. The sub-tables workflow.storage, workflow.kubernetes, workflow.plugin_host, apps.storage and the entries of workflow.plugin_configurations reject unknown keys.

server​

KeyEnvironment variableDefaultMeaning
hostEGRET_SERVER__HOST0.0.0.0Address the HTTP server binds.
portEGRET_SERVER__PORT8080HTTP port.

database​

KeyEnvironment variableDefaultMeaning
urlEGRET_DATABASE__URLpostgres://egret:egret@localhost:5432/egretPostgreSQL connection URL of the metadata database. Migrations run against it on start.
max_connectionsEGRET_DATABASE__MAX_CONNECTIONS10Size of the connection pool.

log​

KeyEnvironment variableDefaultMeaning
filterEGRET_LOG__FILTERinfoA tracing env-filter directive, for example info,egret=debug. An invalid directive falls back to info.
jsonEGRET_LOG__JSONfalseEmit JSON log lines when true, human-readable lines when false.

session and csrf​

KeyEnvironment variableDefaultMeaning
session.cookie_nameEGRET_SESSION__COOKIE_NAMEegret_sessionName of the session cookie.
session.absolute_ttl_hoursEGRET_SESSION__ABSOLUTE_TTL_HOURS24A session ends this long after sign-in, however active. Also the cookie's Max-Age.
session.idle_ttl_minutesEGRET_SESSION__IDLE_TTL_MINUTES60A session ends after this long without a request.
session.secureEGRET_SESSION__SECUREfalseMark the session and OIDC cookies Secure. Set to true whenever the site is served over HTTPS.
csrf.cookie_nameEGRET_CSRF__COOKIE_NAMEegret_csrfName of the CSRF cookie.
csrf.header_nameEGRET_CSRF__HEADER_NAMEX-Egret-CSRFHeader a client sends the CSRF cookie's value in on every state-changing request.

rate_limit​

Two limiters, both in memory per replica. The window and the lockout are in seconds.

KeyEnvironment variableDefaultMeaning
login_max_attemptsEGRET_RATE_LIMIT__LOGIN_MAX_ATTEMPTS5Local sign-in attempts allowed per window, per address and per email. Successful and failed attempts both count.
login_window_secsEGRET_RATE_LIMIT__LOGIN_WINDOW_SECS300Length of the sign-in window.
login_lockout_secsEGRET_RATE_LIMIT__LOGIN_LOCKOUT_SECS300How long a key stays blocked (HTTP 429) once it exceeds the limit.
token_max_attemptsEGRET_RATE_LIMIT__TOKEN_MAX_ATTEMPTS60Requests to the machine identity provider's POST /oauth/token (client credentials) and to the token exchange per window, keyed on address and client id. Requests that repeat an already verified secret are not counted.
token_window_secsEGRET_RATE_LIMIT__TOKEN_WINDOW_SECS60Length of the token window.
token_lockout_secsEGRET_RATE_LIMIT__TOKEN_LOCKOUT_SECS60How long a key stays blocked after exceeding the token limit.

oidc​

External single sign-on. See Authentication setup.

KeyEnvironment variableDefaultMeaning
enabledEGRET_OIDC__ENABLEDfalseTurn on single sign-on. When true, security.secret_key, issuer_url and client_id are required.
issuer_urlEGRET_OIDC__ISSUER_URLempty (required with enabled)The identity provider's issuer, for example http://localhost:8081/realms/egret. Discovery is read from it.
client_idEGRET_OIDC__CLIENT_IDempty (required with enabled)The OIDC client id registered for Egret.
client_secretEGRET_OIDC__CLIENT_SECRETemptyThe OIDC client secret.
redirect_urlEGRET_OIDC__REDIRECT_URLhttp://localhost:8080/api/auth/oidc/callbackThe callback URL registered at the provider. It must be on the origin the browser uses, so the session cookie lands on the app.
scopesEGRET_OIDC__SCOPES["openid","email","profile"]Scopes requested at sign-in.
groups_claimEGRET_OIDC__GROUPS_CLAIMgroupsName of the token claim that lists the user's groups.
post_login_redirectEGRET_OIDC__POST_LOGIN_REDIRECT/Where the browser goes after a successful sign-in.
catalog_audienceEGRET_OIDC__CATALOG_AUDIENCEegret-catalogThe aud value the embedded catalog requires in an engine JWT.

idp​

Egret's own machine identity provider: the issuer of the tokens it mints for engines, the catalog and Data API clients. This is a different issuer from oidc, which describes the external provider people sign in with.

KeyEnvironment variableDefaultMeaning
issuerEGRET_IDP__ISSUERunset (falls back to catalog.public_url)The iss of every token Egret mints and the issuer of /.well-known/openid-configuration. It must be a name clients outside the cluster can resolve. A trailing slash is trimmed. Changing it strands StarRocks engines already provisioned, because their security integration compares the old issuer byte for byte.

security​

KeyEnvironment variableDefaultMeaning
secret_keyEGRET_SECURITY__SECRET_KEYempty (required with oidc.enabled)Base64 key of at least 64 bytes that encrypts the OIDC state cookie. The value in .env.example is public. Generate your own with head -c 64 /dev/urandom | base64.

secrets​

KeyEnvironment variableDefaultMeaning
master_keyEGRET_SECRETS__MASTER_KEYemptyBase64 key of at least 32 bytes used for AES-256-GCM encryption of stored credentials. Empty disables sealing: registering a database or storage connection with a secret then fails. If set, it must decode to 32 bytes or more.

catalog​

The embedded Iceberg REST catalog. See Storage and catalog setup.

KeyEnvironment variableDefaultMeaning
enabledEGRET_CATALOG__ENABLEDfalseRun the catalog in the server process. Requires warehouse, auth_token and the storage credentials.
warehouseEGRET_CATALOG__WAREHOUSEs3://warehouseWarehouse location of the default catalog.
auth_tokenEGRET_CATALOG__AUTH_TOKENempty (required with enabled)Static token for catalog administration.
public_urlEGRET_CATALOG__PUBLIC_URLhttp://localhost:8080Base origin of this server, without /catalog, advertised to catalog clients. Engines in a cluster resolve it, so in Kubernetes it is a Service DNS name. It is also the fallback for idp.issuer.
system_userEGRET_CATALOG__SYSTEM_USERegret-systemStable name of the in-process principal that bootstraps the catalog's default project. Keep it stable across deploys; changing it creates a different system administrator.

storage​

The S3-compatible object store used for the catalog warehouse, query results, workflow files and Data Apps sources.

KeyEnvironment variableDefaultMeaning
endpointEGRET_STORAGE__ENDPOINThttp://localhost:9000S3 endpoint URL. Leave it out of egret.toml for AWS S3.
regionEGRET_STORAGE__REGIONus-east-1S3 region.
bucketEGRET_STORAGE__BUCKETwarehouseBucket name. The bucket must already exist.
access_keyEGRET_STORAGE__ACCESS_KEYempty (required)Access key. The server will not start without it, see Startup checks.
secret_keyEGRET_STORAGE__SECRET_KEYempty (required)Secret key.
path_styleEGRET_STORAGE__PATH_STYLEtrueUse path-style addressing (endpoint/bucket/key). Needed for RustFS and most self-hosted S3 servers.

ranger​

KeyEnvironment variableDefaultMeaning
enabledEGRET_RANGER__ENABLEDfalseServe the Ranger-compatible policy service that engine plugins poll, and turn on policy administration. See Engines and Ranger setup.
auth_tokenEGRET_RANGER__AUTH_TOKENemptyToken the Ranger plugins present to the policy service.

engine​

Limits for queries run from the application.

KeyEnvironment variableDefaultMeaning
max_rowsEGRET_ENGINE__MAX_ROWS100000Most rows a query returns. At least 1.
query_timeout_secsEGRET_ENGINE__QUERY_TIMEOUT_SECS60Per-query timeout. At least 1.
preview_rowsEGRET_ENGINE__PREVIEW_ROWS100Rows returned for a preview. Must not exceed max_rows.
results_prefixEGRET_ENGINE__RESULTS_PREFIXquery-resultsObject-store key prefix for stored query results, inside the storage bucket.

engines​

How Add engine provisions a query engine. Everything under docker applies only when provisioner is docker. See Engines and Ranger setup.

KeyEnvironment variableDefaultMeaning
provisionerEGRET_ENGINES__PROVISIONERautoauto uses Kubernetes when Egret runs in a cluster or finds a kubeconfig, and never picks docker. kubernetes, docker or none choose a backend explicitly. With none, or auto and no cluster, Add engine is disabled.
docker.hostEGRET_ENGINES__DOCKER__HOSTunix:///var/run/docker.sockThe Docker API: unix://, tcp:// or http://.
docker.networkEGRET_ENGINES__DOCKER__NETWORKemptyThe network engine containers join. Required with docker.
docker.projectEGRET_ENGINES__DOCKER__PROJECTemptyValue of the egret.project label on every engine container. Egret never touches a container carrying another project. Required with docker.
docker.callback_urlEGRET_ENGINES__DOCKER__CALLBACK_URLunsetHow engine containers reach Egret, when that differs from the default derived from catalog.public_url. An empty value is refused.
docker.allowed_imagesEGRET_ENGINES__DOCKER__ALLOWED_IMAGES["trinodb/trino"]Image repositories (tag excluded) an engine may use, as a JSON array. Must not be empty.

audit​

KeyEnvironment variableDefaultMeaning
enabledEGRET_AUDIT__ENABLEDtrueRecord authorization decisions. Governance changes are recorded in their own transaction either way.
retention_daysEGRET_AUDIT__RETENTION_DAYS90Rows older than this are pruned hourly. 0 or a negative value means do not prune, and the server logs that it declined to schedule the prune.
channel_capacityEGRET_AUDIT__CHANNEL_CAPACITY8192Size of the in-memory queue. When it is full, events are dropped (the sink is best effort).
batch_sizeEGRET_AUDIT__BATCH_SIZE256Most events written per INSERT.
flush_interval_msEGRET_AUDIT__FLUSH_INTERVAL_MS1000A batch is written at least this often.

automation​

Alerts and reports: the scheduler and the screenshot renderer.

KeyEnvironment variableDefaultMeaning
enabledEGRET_AUTOMATION__ENABLEDtrueRun the schedule ticker. Turn it off on a replica dedicated to serving.
tick_interval_secsEGRET_AUTOMATION__TICK_INTERVAL_SECS30Seconds between ticks.
webhook_allow_hostsEGRET_AUTOMATION__WEBHOOK_ALLOW_HOSTS[]Hosts a webhook may reach even though they resolve into private address space.
renderer_urlEGRET_AUTOMATION__RENDERER_URLhttp://egret-renderer:8080Base URL of the egret-renderer service, reachable from this server.
public_urlEGRET_AUTOMATION__PUBLIC_URLhttp://egret:8080Base URL the renderer uses to reach this server (in a cluster, its own Service name).
browser_urlEGRET_AUTOMATION__BROWSER_URLunset (falls back to public_url)Base URL a person opens, used for the links in notifications.

data_api​

KeyEnvironment variableDefaultMeaning
access_log_retention_daysEGRET_DATA_API__ACCESS_LOG_RETENTION_DAYS90Data API access-log rows older than this are pruned hourly. 0 means do not prune.
public_urlEGRET_DATA_API__PUBLIC_URLunset (falls back to the idp issuer, then catalog.public_url)Base URL a consumer outside the cluster uses. It is stamped into the generated OpenAPI document and the token endpoint handed to a new client.
replicasEGRET_DATA_API__REPLICAS1How many replicas of the backend run. The Helm chart sets it. Above 1 with no shared_store_url, the server refuses to start.
shared_store_urlEGRET_DATA_API__SHARED_STORE_URLunsetRedis or Valkey URL that holds the Data API rate-limit buckets and response cache across replicas, for example redis://valkey:6379/1. Unset means process-local state.

workflow​

Switches and limits for the workflow engine. Both loops default to off.

KeyEnvironment variableDefaultMeaning
webhooks_enabledEGRET_WORKFLOW__WEBHOOKS_ENABLEDfalseMount the anonymous webhook routes (POST /workflows/v1/{ws}/executions/webhook/...). The key in the URL is the only credential. When false the routes are not mounted at all.
worker_enabledEGRET_WORKFLOW__WORKER_ENABLEDfalseStart the claim loop and the lease reaper. With it off, an execution is created and nothing advances it.
scheduler_enabledEGRET_WORKFLOW__SCHEDULER_ENABLEDfalseStart the trigger loop, so cron: schedule and flow triggers fire. It needs the worker on to be useful.
tick_interval_secsEGRET_WORKFLOW__TICK_INTERVAL_SECS1Seconds between claim ticks.
batchEGRET_WORKFLOW__BATCH8Most task runs one claim tick takes.
reaper_interval_secsEGRET_WORKFLOW__REAPER_INTERVAL_SECS60Seconds between reaper passes.
working_timeout_sEGRET_WORKFLOW__WORKING_TIMEOUT_S3600How long a lease may go unreleased before the reaper hands the run back. Too short and a slow live task is run twice; too long and a task of a dead replica stays stuck.
container_default_timeout_sEGRET_WORKFLOW__CONTAINER_DEFAULT_TIMEOUT_S3600Timeout of a script or container task that declares none. Other task types run unbounded.
kill_poll_msEGRET_WORKFLOW__KILL_POLL_MS5000Milliseconds between a running task's checks for a kill request. Minimum 100.
trigger_interval_secsEGRET_WORKFLOW__TRIGGER_INTERVAL_SECS1Seconds between scheduler passes.
log_retention_daysEGRET_WORKFLOW__LOG_RETENTION_DAYS30Stored task log lines older than this are deleted hourly. 0 keeps them for ever.
storage_retention_daysEGRET_WORKFLOW__STORAGE_RETENTION_DAYS30Execution files are kept this long after the execution ends. 0 keeps them for ever.
kept_container_retention_daysEGRET_WORKFLOW__KEPT_CONTAINER_RETENTION_DAYS7How long a container or pod kept with taskRunner.delete: false outlives its run. 0 keeps it for ever.
log_run_max_linesEGRET_WORKFLOW__LOG_RUN_MAX_LINES10000Most log lines stored per task-run attempt. Past it the task keeps running and one warning line says how many were withheld.
log_run_max_bytesEGRET_WORKFLOW__LOG_RUN_MAX_BYTES10485760Most bytes of log text stored per task-run attempt (10 MiB).
container_runnerEGRET_WORKFLOW__CONTAINER_RUNNERnoneWhere script tasks run: none (no script handler), docker (local development only) or kubernetes (one pod per task-run attempt). Any value other than none requires the storage credentials and plugin_host.image.
plugin_configurationsEGRET_WORKFLOW__PLUGIN_CONFIGURATIONSempty listPer-plugin settings in Kestra's kestra.plugins.configurations shape: a list of {type, values}. The only values read are allowed-images (glob patterns for script task images; empty allows no image) and, on the kestra entry, allowed-types (glob patterns for plugin task types).

workflow.storage​

KeyEnvironment variableDefaultMeaning
prefixEGRET_WORKFLOW__STORAGE__PREFIXworkflow/Object-key prefix for execution files. Must end with /, not start with /, and be at most 200 bytes.
max_file_bytesEGRET_WORKFLOW__STORAGE__MAX_FILE_BYTES1073741824Largest single file (1 GiB).
max_task_bytesEGRET_WORKFLOW__STORAGE__MAX_TASK_BYTES5368709120Most bytes one task run may write in all (5 GiB).
max_read_bytesEGRET_WORKFLOW__STORAGE__MAX_READ_BYTES10485760Most bytes a read() returns into a template render (10 MiB). Minimum 4096.
max_namespace_filesEGRET_WORKFLOW__STORAGE__MAX_NAMESPACE_FILES10000Most namespace files one listing, search or namespace-file operation may see.

workflow.kubernetes​

Read only when container_runner is kubernetes. None of it is settable by a flow author.

KeyEnvironment variableDefaultMeaning
namespaceEGRET_WORKFLOW__KUBERNETES__NAMESPACEegret-tasksNamespace task pods are created in.
default_resourcesEGRET_WORKFLOW__KUBERNETES__DEFAULT_RESOURCES__<REQUEST|LIMIT>__<CPU|MEMORY|EPHEMERAL_STORAGE>request 100m / 128Mi / 256Mi; limit 1 / 512Mi / 10GiRequests and limits a task gets when its taskRunner.resources says nothing.
max_resourcesEGRET_WORKFLOW__KUBERNETES__MAX_RESOURCES__<REQUEST|LIMIT>__<CPU|MEMORY|EPHEMERAL_STORAGE>limit 2 / 2Gi / 10Gi; no request capThe most a task may ask for; larger values are capped.
image_pull_secretsEGRET_WORKFLOW__KUBERNETES__IMAGE_PULL_SECRETS[]Existing dockerconfigjson Secrets in the task namespace, attached to every task pod.
run_as_userEGRET_WORKFLOW__KUBERNETES__RUN_AS_USER1000Uid of every container in a task pod. Must be positive.
helper_imageEGRET_WORKFLOW__KUBERNETES__HELPER_IMAGEegret-task-helper:devImage that moves input and output files in and out of a task pod.

workflow.plugin_host​

KeyEnvironment variableDefaultMeaning
imageEGRET_WORKFLOW__PLUGIN_HOST__IMAGEunset (required when container_runner is not none)Image that runs Kestra plugin tasks (type: kestra.<class>), built from deploy/docker/plugin-host.Dockerfile.
jvm_max_heapEGRET_WORKFLOW__PLUGIN_HOST__JVM_MAX_HEAP384mThe JVM -Xmx: digits and one optional unit letter (k, m, g).
kill_grace_sEGRET_WORKFLOW__PLUGIN_HOST__KILL_GRACE_S15Seconds between SIGTERM and SIGKILL for a timed-out plugin task. Minimum 3.

starrocks​

KeyEnvironment variableDefaultMeaning
jdbc_drivers.<dialect>.driver_urlEGRET_STARROCKS__JDBC_DRIVERS__<DIALECT>__DRIVER_URLunsetRepoint the JDBC driver jar a StarRocks jdbc catalog downloads, at an internal mirror or a file:/// path in the FE image. <dialect> is postgresql, mysql, mariadb, oracle, sqlserver or clickhouse.
jdbc_drivers.<dialect>.driver_classEGRET_STARROCKS__JDBC_DRIVERS__<DIALECT>__DRIVER_CLASSunsetThe driver class for that dialect. Egret compiles in a pinned driver for each dialect, and this section only repoints it.

apps​

The Data Apps query gateway and the pods that run marimo. See Data Apps.

KeyEnvironment variableDefaultMeaning
max_rowsEGRET_APPS__MAX_ROWS10000Row cap per gateway query.
timeout_secsEGRET_APPS__TIMEOUT_SECS60Per-query engine timeout.
session_idle_secsEGRET_APPS__SESSION_IDLE_SECS1800An app token dies after this long unused. Must not exceed session_absolute_secs.
session_absolute_secsEGRET_APPS__SESSION_ABSOLUTE_SECS28800An app token dies this long after minting.
rate_maxEGRET_APPS__RATE_MAX20Gateway calls allowed per token per window.
rate_window_secsEGRET_APPS__RATE_WINDOW_SECS2Window length; a 429 holds that token for one full window.
originEGRET_APPS__ORIGINemptyOrigin where marimo is served, for example https://apps.egret.example. A sibling subdomain, never another port. Empty disables the iframe (the ticket endpoint answers 503).
egret_originEGRET_APPS__EGRET_ORIGINemptyEgret's own browser-facing origin, the only one allowed to frame the apps origin. Required when origin is set, and must differ from it.
ticket_ttl_secsEGRET_APPS__TICKET_TTL_SECS30How long a one-time ticket may wait to be redeemed.
cookie_ttl_secsEGRET_APPS__COOKIE_TTL_SECS28800Lifetime of the apps-origin cookie.
listenEGRET_APPS__LISTEN0.0.0.0:8081Where the apps host listens. A separate listener from the API.

apps.pod​

KeyEnvironment variableDefaultMeaning
launcherEGRET_APPS__POD__LAUNCHERnonenone (no pods), subprocess (local development, one marimo process per author) or kubernetes (one hardened pod per author per workspace). Anything but none needs apps.origin and callback_url.
ready_timeout_secsEGRET_APPS__POD__READY_TIMEOUT_SECS60How long a request waits for a cold pod.
idle_secsEGRET_APPS__POD__IDLE_SECS1800An edit pod unused this long is stopped. At least 60.
callback_urlEGRET_APPS__POD__CALLBACK_URLemptyBase URL pods call back to, Egret's in-cluster Service, for example http://egret:8080.
namespaceEGRET_APPS__POD__NAMESPACEegret-appsKubernetes namespace of the pods.
imageEGRET_APPS__POD__IMAGEegret-apps:devPod image.
image_pull_policyEGRET_APPS__POD__IMAGE_PULL_POLICYIfNotPresentKubernetes image pull policy.
cpu_request, mem_requestEGRET_APPS__POD__CPU_REQUEST, ..._MEM_REQUEST250m, 512MiPod resource requests.
cpu_limit, mem_limitEGRET_APPS__POD__CPU_LIMIT, ..._MEM_LIMIT1000m, 2GiPod resource limits.
pull_secretEGRET_APPS__POD__PULL_SECRETunsetExisting dockerconfigjson Secret for pulling the image.
commandEGRET_APPS__POD__COMMAND[]subprocess launcher: the command that starts the launcher entrypoint.
work_dirEGRET_APPS__POD__WORK_DIR/tmp/egret-appssubprocess launcher: parent directory of each pod's working directory.
config_dirEGRET_APPS__POD__CONFIG_DIRemptysubprocess launcher: the locked marimo configuration directory.
venv_shim_dirEGRET_APPS__POD__VENV_SHIM_DIRemptysubprocess launcher: the venv shim directory run pods need.
run_idle_secsEGRET_APPS__POD__RUN_IDLE_SECS300A run pod (a viewer of a published version) unused this long is stopped.
run_session_capEGRET_APPS__POD__RUN_SESSION_CAP8Open sessions (tabs) of the one viewer a run pod serves before a new one gets 503. At least 1.
run_kernel_modeEGRET_APPS__POD__RUN_KERNEL_MODEthreadthread or forced_ipc. forced_ipc is not a supported production path.

apps.storage​

KeyEnvironment variableDefaultMeaning
prefixEGRET_APPS__STORAGE__PREFIXapps/Object-key prefix for app drafts and versions. Must end with / and not start with /.

Variables outside the configuration file​

These are read directly from the environment.

VariableUsed byMeaning
EGRET_ADMIN_EMAILegret init, egret workspace add-groupEmail of the bootstrap administrator. Default admin@egret.local.
EGRET_ADMIN_PASSWORDegret initPassword of the bootstrap administrator. If unset, a random one is generated and printed once.
EGRET_ENGINE_TLS_INSECUREQuery connectors and the engine monitor1, true or yes skip TLS certificate verification when connecting to engines. Development only.
DATABASE_URLsqlx tooling and the test suiteUsed by compile-time query checking and tests, not by the server (which reads EGRET_DATABASE__URL). .env.example sets both.

Startup checks​

egret serve validates the configuration before it listens, and every other subcommand that touches the database runs the same check. A failure prints one line and exits. These are the rules:

RuleMessage
oidc.enabled needs security.secret_key (base64, at least 64 bytes)oidc.enabled requires security.secret_key (base64, >=64 bytes)
oidc.enabled needs an issuer and a client idoidc.enabled requires issuer_url and client_id
catalog.enabled needs a warehouse and a tokencatalog.enabled requires warehouse and auth_token
catalog.enabled needs the storage credentialscatalog.enabled requires storage access_key/secret_key/bucket
secrets.master_key, when set, must decode to 32 bytes or moresecrets.master_key must be base64 of >=32 bytes
Always: storage.bucket, access_key and secret_keythe apps API requires [storage] bucket, access_key, secret_key ...
engine.max_rows and query_timeout_secs are at least 1; preview_rows is at most max_rowsengine.max_rows and engine.query_timeout_secs must be >= 1
workflow.kill_poll_ms is at least 100workflow.kill_poll_ms: ... is below the minimum 100
workflow.container_runner other than none needs the storage credentials and plugin_host.imageworkflow.container_runner other than none requires [storage] ...
apps.origin set: both origins are scheme://host[:port], differ from each other, and the TTLs are at least 1apps.origin must differ from apps.egret_origin ...
apps.pod.launcher is none, subprocess or kubernetes, with the keys each needsapps.pod.launcher must be none, subprocess or kubernetes ...
More than one data_api.replicas needs data_api.shared_store_urlThe server refuses to start.
The storage credentials are required even if you never use object storage

The apps API stores draft and version content in the storage bucket regardless of the pod launcher, so the check applies on every start, including egret migrate and egret init. A copy of .env.example alone does not satisfy it. See the Quick start.

Further reading​