Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Camel.toml schema

Camel.toml is the operator surface for rust-camel. The file is TOML, parsed by CamelConfig::from_file, and deserialized into the CamelConfig struct. Most fields live under [default] and merge with named profiles ([production], [staging], ...) per the profile rules described in Configuration.

A minimal file sets the route discovery glob and the log level. Everything else has a runtime default.

[default]
routes = ["routes/**/*.yaml"]
log_level = "INFO"

A fuller file adds supervision, tracing, and shared component defaults. Profiles override per environment.

[default]
routes = ["routes/**/*.yaml"]
log_level = "INFO"

# Optional supervision configuration
[default.supervision]
max_attempts = 5
initial_delay_ms = 1000
backoff_multiplier = 2.0
max_delay_ms = 60000

# Optional tracing configuration
[default.observability.tracer]
enabled = true
detail_level = "minimal"

[default.observability.tracer.outputs.stdout]
enabled = true
format = "json"

# Component defaults (optional) - apply to all endpoints unless overridden by URI
# Uncomment to enable global component settings:

# [default.components.http]
# connect_timeout_ms = 5000
# response_timeout_ms = 30000
# max_connections = 100
# allow_internal = false

# [default.components.kafka]
# brokers = "localhost:9092"
# group_id = "camel"
# session_timeout_ms = 45000

# [default.components.redis]
# host = "localhost"
# port = 6379

# [default.components.sql]
# max_connections = 5
# min_connections = 1
# idle_timeout_secs = 300

# [default.components.file]
# delay_ms = 500
# read_timeout_ms = 30000

# [default.components.container]
# docker_host = "unix:///var/run/docker.sock"

# Optional persistent idempotent repository (opt-in). When set under the
# active profile, registers a "redb" backend for `idempotent_consumer` steps;
# keys persist across restart. The default "memory" repo stays available.
# durability: "immediate" (default, fsync per key) | "eventual" (no fsync, faster)
# [default.idempotent_repo]
# path = ".camel/idempotent.redb"
# durability = "immediate"

[development]
log_level = "DEBUG"

[production]
log_level = "ERROR"

Top-level fields

The fields below live directly under [default]. They are the spine of the file. Every other section in this page is optional.

FieldTypeDefaultDescription
routesarray of strings[]Glob patterns for route files (YAML or JSON). Discovery runs at startup and on every file change when watch is enabled.
watchboolfalseEnable the file watcher. When true, route file changes trigger a hot reload. See Hot reload.
watch_debounce_msinteger (ms)300Delay after the last file event before a reload. Increase if one save triggers several reloads.
log_levelstring"INFO"One of TRACE, DEBUG, INFO, WARN, ERROR.
timeout_msinteger (ms)5000Per-exchange timeout enforced by the runtime. Must be > 0.
drain_timeout_msinteger (ms)10000Maximum time the runtime waits for in-flight exchanges to finish on shutdown. Must be > 0.
includearray of stringsPaths to other TOML files merged before the profile pass. See Configuration.

The watcher and the file are wired through camel-core::reload_watcher::watch_and_reload (see ADR-0004). The --watch and --no-watch CLI flags override this field at startup.

[binds."<addr>"]

Per-bind public-exposure acknowledgements (ADR-0061 Rule 4). When any route on a NON-loopback bind (http://0.0.0.0:8080, wss://0.0.0.0:9000, an MCP bind, …) compiles to a Public security plan, startup refuses unless the bind carries an explicit acknowledgement; an acknowledged exposure warns permanently on every start (ADR-0052 rule 3). Loopback binds (127.0.0.1, localhost, ::1) need no acknowledgement.

[binds."0.0.0.0:8080"]
allow_public_exposure = true
FieldTypeDefaultDescription
allow_public_exposureboolfalseAcknowledge that this bind intentionally serves unauthenticated routes. Required for non-loopback Public binds; refusal names the bind and the routes.

[components]

Component configuration is untyped TOML keyed by component name. Each component bundle parses its own block. The schema below is the union of fields the runtime and core components recognize.

[components.http]
connect_timeout_ms = 5000
response_timeout_ms = 30000
allow_internal = false

[components.kafka]
brokers = "localhost:9092"
group_id = "camel"

The full per-component schema lives in each component's documentation. The Kafka block is the most complex and supports a [components.kafka.brokers_named.<name>] sub-table for pre-configured clusters referenced from URIs with ?brokerName=<name>. See Kafka for the named-broker fields.

Common fieldTypeDefaultDescription
brokersstring or list of stringscomponent-specificConnection string for the underlying client. Kafka accepts a comma-separated string.
host, portstring, integercomponent-specificListen address for components that open servers.
connect_timeout_msintegercomponent-specificTimeout for establishing a connection.
allow_internalboolfalseAllow private/loopback endpoints. Set true only for local development.

Custom component bundles follow the same convention. A bundle named echo reads its config from [components.echo]. See Custom component for the bundle contract.

[supervision]

The runtime uses these knobs to restart a failed Consumer with capped exponential backoff. Defaults match a one-second start, doubling each attempt, capped at one minute, with five attempts.

FieldTypeDefaultDescription
max_attemptsinteger or null5Maximum restart attempts. null retries forever.
initial_delay_msinteger (ms)1000Delay before the first attempt. Must be > 0.
backoff_multiplierfloat2.0Multiplier applied to the delay after each failure. Must be >= 1.0.
max_delay_msinteger (ms)60000Cap on the per-attempt delay. Must be > 0.

[observability]

The observability block holds five optional sub-tables. The [observability.tracer] block configures the built-in tracing layer, and [observability.metrics] gates its metric families. The other three activate optional exporters.

FieldTypeDefaultDescription
tracertable(built-in defaults)Built-in tracing layer config.
metricstable(built-in defaults)Metric-family levers. Absent table means all defaults.
oteltableabsentOpenTelemetry exporter. Absent disables OTLP.
prometheustableabsentPrometheus scrape endpoint. Absent disables the endpoint.
healthtableabsentHTTP health/readiness endpoint. Absent disables the endpoint.

Span and metric enablement are independent:

  • [observability.tracer] enabled gates SPAN creation only. With Prometheus (or OTel) active, an explicit enabled = false still runs the tracer pipeline so metric families keep flowing; no spans are created.
  • The pipeline itself is turned off only when neither tracing nor any exporter is active. The [observability.metrics] levers below can suppress individual non-error families but never disable the pipeline.

[observability.metrics]

Metric-family levers. Unknown keys fail at load, consistent with the sibling observability tables. There is no lever for the error family: camel_errors_total is structurally non-disableable and is exported regardless of any combination of these keys.

FieldTypeDefaultDescription
enabledbooltrueMaster switch for the non-error metric families. false suppresses exchanges, duration, and component families; errors always flow.
exchangebooltrueOpt-out for the camel_exchanges_total family. Only takes effect when enabled is true.
durationbooltrueOpt-out for the camel_exchange_duration_seconds family. Only takes effect when enabled is true.
componentsboolfalseOpt-in for the component-operations metric family (camel_component_operations_total).

[observability.otel]

OTLP export configuration. The protocol and sampler accept the values listed below; values not in the enum fail at load.

FieldTypeDefaultDescription
enabledboolfalseMaster switch for OTLP export.
endpointstring"http://localhost:4317"OTLP collector endpoint.
service_namestring"rust-camel"Resource attribute identifying the service.
protocolstring"grpc"OTLP transport: grpc or http.
samplerstring"always_on"Sampling strategy: always_on, always_off, ratio.
sampler_ratiofloatnullSampling probability for the ratio strategy. Range 0.0-1.0.
metrics_interval_msinteger (ms)60000Period for the metrics export loop. Must be > 0.
logs_enabledbooltrueInclude log records in the OTLP stream.
resource_attrstable{}Extra resource attributes attached to every export.

[observability.prometheus]

FieldTypeDefaultDescription
enabledboolfalseStart the scrape endpoint.
hoststring"0.0.0.0"Bind address.
portinteger9090Bind port.

[observability.health]

FieldTypeDefaultDescription
enabledboolfalseStart the HTTP health endpoint.
hoststring"0.0.0.0"Bind address.
portinteger8081Bind port.
handler_timeout_msinteger (ms)6000Per-probe timeout. Must exceed the internal 5s registry tick.
forced_ttl_msinteger (ms) or nullnullOptional TTL for forced-unhealthy entries. Disabled by default.

[security]

The security block holds five optional sub-tables. Pick one. Most deployments choose exactly one of oidc, native, or keycloak. The permissions and policies sub-tables extend the chosen identity layer with authorization.

Placeholders in Camel.toml use ${env:VAR} and ${env:VAR:-default}. The :- separator is native: default is used when VAR is unset. An unset variable without a default aborts load, naming the field. The legacy {{...}} syntax is rejected with an error pointing at the ${env:} forms. See Environment variable interpolation.

[security.keycloak]
server_url = "https://kc.example.com"
realm = "my-realm"
client_id = "camel"
client_secret = "${env:KC_SECRET}"
FieldTypeDefaultDescription
oidctableabsentGeneric OIDC token validation.
nativetableabsentBuilt-in static credential store.
keycloaktableabsentKeycloak realm with validation, JWKS, introspection, and UMA.
permissionstable of tablesabsentNamed permission evaluators keyed by policy name.
policiestableabsentRegistry of WASM security policies referenced by route configuration.

[security.oidc]

FieldTypeDefaultDescription
issuerstring(required)OIDC issuer URL used to discover endpoints.
jwks_uristring(required)JWKS endpoint.
audiencearray of strings[]Required aud claim values.
client_idstringnullOAuth2 client ID.
client_secretstringnullOAuth2 client secret. Resolves ${env:VAR}; unset variable without default fails load.
token_endpointstringnullToken endpoint for client credentials flows.
introspection_endpointstringnullToken introspection endpoint.

[security.native]

The native block is a static credential store with no external identity provider. Set at least one credential: a scalar bearer_token or api_key, or one or more [[security.native.credentials]] entries. A config with no credential fails load.

FieldTypeDefaultDescription
subjectstring(required)Principal name for the scalar bearer_token and api_key identities.
issuerstring"native"Issuer recorded on synthesized principals. null falls back to "native".
bearer_tokenstringnullPre-issued bearer token. Resolves ${env:VAR}; unset variable without default fails load.
api_keystringnullPre-shared API key. Resolves ${env:VAR}; unset variable without default fails load.
rolesarray of strings[]Roles granted to the scalar identities.
scopesarray of strings[]Scopes granted to the scalar identities.
credentialsarray of tables[]Static credentials, each with its own subject, roles, and scopes.

[[security.native.credentials]] array elements:

FieldTypeDefaultDescription
subjectstring(required)Principal name for this credential. Must not be empty.
secret_envstringabsentEnvironment variable holding the secret. Read at startup; fails closed if unset or empty.
secretstringabsentPlaintext secret. Logged with a warning at startup; use secret_env in production.
rolesarray of strings[]Roles granted to this credential's principal.
scopesarray of strings[]Scopes granted to this credential's principal.

Each credentials entry must set exactly one of secret_env or secret; setting both or neither fails at load. The block uses deny_unknown_fields, so unknown keys are rejected at load.

[security.keycloak]

FieldTypeDefaultDescription
server_urlstring(required)Keycloak base URL.
realmstring(required)Realm name.
client_idstring(required)Client ID.
client_secretstring(required)Client secret. Resolves ${env:VAR}; unset variable without default fails load.
validationtable(defaults below)Token validation options.
jwkstable(defaults below)JWKS cache tuning.
introspectiontable(defaults below)Introspection cache tuning.
umatableabsentUMA authorization provider.
allow_internalboolfalseAllow HTTP and private addresses. Set true only for local Keycloak.

[security.keycloak.validation] fields:

FieldTypeDefaultDescription
methodstring"local"Validation method. "local" validates signature and claims locally.
audiencearray of strings[]Required aud claim values.
clock_skew_secsinteger (s)30Tolerance for exp and nbf claims.

[security.keycloak.jwks] fields:

FieldTypeDefaultDescription
cache_ttl_secsinteger (s)3600How long the JWKS cache holds keys.
refresh_skew_secsinteger (s)60Refresh the cache this many seconds before expiry.

[security.keycloak.introspection] fields:

FieldTypeDefaultDescription
max_entriesinteger10000Maximum cached introspection results.
default_ttl_secsinteger (s)60TTL for positive results.
negative_ttl_secsinteger (s)5TTL for negative results.

[security.permissions.<name>]

Named permission evaluators. A route references the name through route configuration.

[security.permissions.invoice-policy]
provider = "wasm"
path = "./policies/invoice-policy.wasm"

[security.permissions.invoice-policy.config]
mode = "enforce"

[security.permissions.invoice-policy.cache]
positive_ttl_secs = 60
negative_ttl_secs = 10
FieldTypeDefaultDescription
providerstring(required)Provider key. Currently wasm.
pathstringnullProvider-specific path. WASM providers need a .wasm file.
configtableabsentKey-value pairs passed to the provider.
cachetable(defaults below)Result cache tuning.
limitstableabsentWASM limits. See WASM limits.

[security.permissions.<name>] cache fields:

FieldTypeDefaultDescription
positive_ttl_secsinteger (s)30TTL for allow decisions.
negative_ttl_secsinteger (s)5TTL for deny decisions.
max_entriesinteger10000Cache size.

[security.policies.wasm.<name>]

Registry of named WASM security policies. Each entry is a path plus limits plus a config map.

[security.policies.wasm.corp-auth]
path = "plugins/authz.wasm"

[security.policies.wasm.corp-auth.limits]
timeout-secs = 30

[security.policies.wasm.corp-auth.config]
ldap_url = "ldap://corp"
FieldTypeDefaultDescription
pathstring(required)Path to the .wasm file. Relative to the project root or absolute.
limitstableabsentWASM limits. See WASM limits.
configtable{}Key-value pairs passed to the guest init().

[runtime_journal]

The runtime event journal. When unset, runtime state is ephemeral and lost on restart. Set a path to enable a redb-backed journal.

FieldTypeDefaultDescription
pathstring(required)Path to the .db file. Created if it does not exist. Must not be empty.
durabilitystring"immediate"immediate fsyncs on every commit. eventual skips fsync for throughput.
compaction_threshold_eventsinteger10000Trigger compaction after this many events. Must be > 0.

[idempotent_repo]

Persistent idempotent repository for the Idempotent Consumer EIP. When unset, the runtime uses the in-memory MemoryIdempotentRepository, which is bounded and ephemeral.

backend selects the store. "redb" is the default. The redb repository registers under the name "redb". The redis repository registers under the name "redis", and route steps select it with repository = "redis". Redis keys survive a process restart and are shared by every process that connects to the same Redis.

FieldTypeDefaultDescription
backendstring"redb""redb" (persistent on-disk store) or "redis" (persistent, shared across processes).
namestringabsentRegistration-name override (also the redis keyspace segment). Defaults: "redb"/"redis". Allowed charset [A-Za-z0-9:_-].
pathstring(required for redb)Path to the .redb file. Must not be empty. Redb only.
durabilitystring"immediate"immediate fsyncs on every key. eventual skips fsync. Redb only.
urlstring(required for redis)Standalone endpoint, redis:// or rediss://. Mutually exclusive with sentinel_nodes. Redis only.
sentinel_nodesstring array(alternative to url)Sentinel node addresses. Mutually exclusive with url. Redis only.
master_namestring(required with sentinel_nodes)Master name resolved through the sentinels. Redis only.
sentinel_usernamestringabsentSentinel AUTH username. Redis only.
sentinel_passwordstringabsentSentinel AUTH password. Redacted from Debug output. Redis only.
passwordstringabsentData-node AUTH password. Redacted from Debug output. Rejected in url mode. Redis (sentinel mode) only.
usernamestringabsentData-node AUTH username. Redacted from Debug output. Rejected in url mode. Redis (sentinel mode) only.
dbintegerabsentData-node database index. Valid range 0 to 16383. Defaults to 0 when absent. Rejected in url mode. Redis (sentinel mode) only.
key_prefixstring"camel:idem"Redis key prefix for this repository's keyspace. Allowed charset [A-Za-z0-9:_-]. Redis only.

In url mode the URI carries the password and the database. The password rides the userinfo and the database rides the ?db=N query parameter, as in redis://:pass@host:port?db=N. A username in the URI is not supported.

A runnable redis configuration lives in examples/redis-repositories:

[default.idempotent_repo]
backend = "redis"
url = "redis://127.0.0.1:6379"

[cache_repo]

Optional cache repository configuration. When unset, only the default "memory" cache repository is registered. With backend = "redb", a persistent "persistent" repository (redb-backed) is registered alongside "memory". With backend = "redis", a shared "redis" repository is registered alongside "memory", and route steps select it with repository = "redis".

FieldTypeDefaultDescription
backendstring"memory""memory" (moka-backed, size-eviction only), "redb" (persistent, survives restarts), or "redis" (persistent, shared across processes).
namestringabsentRegistration-name override (also the redis keyspace segment). Defaults: "memory"/"persistent"/"redis" (the redb default is a kept asymmetry). The memory backend only honors it when max_capacity is set.
pathstring(required for redb)Path to the .redb file. Created if it does not exist. Must not be empty. Redb only.
stale_retentionduration string7d (wiring fallback)How long after expiry a stale entry stays readable. Redb: the sweep reclaims the entry after this window. Redis: the key expires at expires_at + stale_retention. Duration strings, for example "168h", "7d", "30m". The value in force at set() time applies; later changes are not retroactive (see ADR-0065). Redb and redis.
max_entriesinteger1000000Maximum entry count for the redb backend; new-key writes are rejected at the cap. Redb only.
cache_sizebyte-size string(required for redb)Bounds the redb page cache, e.g. "384MB", "256MiB", or plain bytes (1073741824). Decimal suffixes are powers of 1000, binary suffixes powers of 1024. Redb only.
sweep_intervalduration string1hHow often the redb background sweep runs. Must be positive. Redb only.
payloadstring"inline"Payload storage mode. "inline" keeps payload bytes in the repository entry. "disk" offloads payload bodies to blob files under payload_dir. Rejected on the memory backend. Redb and redis.
payload_dirpath string(required when disk)Directory holding offloaded payload files. Required and non-empty when payload = "disk"; rejected otherwise. No default. Supports ${env:} strict interpolation. Redb and redis.
payload_sweep_intervalduration string1hHow often the offloaded-payload sweep runs when payload = "disk". The interval also widens every blob's death epoch as a grace window. Must be at least one second. Redb and redis.
payload_max_ttlduration string720h (30d)Expiry fabricated for entries stored without a TTL when payload = "disk", so index row and blob file share one death timeline. Must be at least one second. Redb and redis.
max_capacityinteger10000 (default memory repo)Entry cap for the memory backend. Memory only.
urlstring(required for redis)Standalone endpoint, redis:// or rediss://. Mutually exclusive with sentinel_nodes. Redis only.
sentinel_nodesstring array(alternative to url)Sentinel node addresses. Mutually exclusive with url. Redis only.
master_namestring(required with sentinel_nodes)Master name resolved through the sentinels. Redis only.
sentinel_usernamestringabsentSentinel AUTH username. Redis only.
sentinel_passwordstringabsentSentinel AUTH password. Redacted from Debug output. Redis only.
passwordstringabsentData-node AUTH password. Redacted from Debug output. Rejected in url mode. Redis (sentinel mode) only.
usernamestringabsentData-node AUTH username. Redacted from Debug output. Rejected in url mode. Redis (sentinel mode) only.
dbintegerabsentData-node database index. Valid range 0 to 16383. Defaults to 0 when absent. Rejected in url mode. Redis (sentinel mode) only.
key_prefixstring"camel:cache"Redis key prefix for this repository's keyspace. Allowed charset [A-Za-z0-9:_-]. Redis only.

In url mode the URI carries the password and the database. The password rides the userinfo and the database rides the ?db=N query parameter, as in redis://:pass@host:port?db=N. A username in the URI is not supported.

Fields that do not apply to the configured backend are rejected at validation (fail-closed), and a malformed cache_size, sweep_interval, stale_retention, payload_sweep_interval, or payload_max_ttl fails validation with an error naming the field. The same applies to payload fields set while payload is inline or unset.

A runnable redis configuration lives in examples/redis-repositories:

[default.cache_repo]
backend = "redis"
url = "redis://127.0.0.1:6379"
stale_retention = "30m"

[stream_caching]

The Stream Cache step buffers stream bodies past a threshold so the body can be read more than once. The cache applies to the whole runtime, not per route.

FieldTypeDefaultDescription
thresholdinteger (bytes)camel_api::stream_cache::DEFAULT_STREAM_CACHE_THRESHOLDBodies below this size pass through unread. Bodies above this size are buffered.

[platform]

Platform selection for leader election, readiness, and identity. Defaults to noop, which always reports leader and ready. Set type = "kubernetes" to enable leader election through a Kubernetes lease.

FieldTypeDefaultDescription
typestring"noop"noop or kubernetes.

[platform] with type = "kubernetes" accepts:

FieldTypeDefaultDescription
namespacestringnullNamespace for the lease object. Defaults to the pod's namespace.
lease_name_prefixstring"camel-"Prefix on the lease object name.
lease_duration_secsinteger (s)15Lease lifetime. Must be > 0.
renew_deadline_secsinteger (s)10Maximum time the leader can hold the lease between renewals. Must be > 0.
retry_period_secsinteger (s)2How often a non-leader retries acquisition. Must be > 0.
jitter_factorfloat0.2Randomisation applied to the retry period. Range 0.0-1.0.

[languages]

The languages block tunes the resource limits for the in-process scripting engines. Each sub-block is optional. Unset fields fall back to the rust-camel runtime default, never to the upstream engine's unlimited default.

[languages.rhai.limits]

Rhai sandbox limits.

FieldTypeDefaultDescription
max-operationsintegerruntime defaultMaximum operations per script. Counter resets each call.
max-string-sizeinteger (bytes)runtime defaultMaximum string size in bytes.
max-array-sizeintegerruntime defaultMaximum array size in elements.
max-map-sizeintegerruntime defaultMaximum map size in key-value pairs.
max-expression-depthintegerruntime defaultMaximum expression nesting depth.
max-function-expression-depthintegerruntime defaultMaximum nesting depth for function call expressions.
execution-timeout-msinteger (ms)runtime defaultWall-clock timeout enforced by the consuming code.

[languages.js.limits]

Boa JavaScript engine limits.

FieldTypeDefaultDescription
execution-timeout-msinteger (ms)runtime defaultWall-clock timeout enforced by the consuming code.
max-loop-iterationsintegerruntime defaultMaximum loop iterations before Boa terminates.
max-recursion-depthintegerruntime defaultMaximum recursion depth for function calls.
max-stack-sizeinteger (slots)runtime defaultMaximum VM stack size in slots, not bytes.

[languages.minijinja.limits]

MiniJinja template engine limits.

FieldTypeDefaultDescription
max-template-source-sizeinteger (bytes)runtime defaultMaximum compiled template source size.
max-context-sizeinteger (bytes)runtime defaultMaximum serialised context size.
max-output-sizeinteger (bytes)runtime defaultMaximum rendered output size.
fuelintegerruntime defaultMiniJinja VM instruction budget.
max-recursion-depthintegerruntime defaultMaximum recursion depth for includes and blocks.
execution-timeout-msinteger (ms)runtime defaultWall-clock timeout enforced by the consuming code.

[components.template.limits]

The external Template component's resource limits. Set any subset of fields. Unset fields fall back to the resolved defaults listed below.

[components.template.limits]
max-total-source-bytes = 16777216
max-include-count = 64
max-include-depth = 16
max-template-size = 1048576
reload-timeout-ms = 5000
FieldTypeResolved defaultDescription
max-total-source-bytesinteger (bytes)16777216 (16 MiB)Maximum total source bytes across a template dependency closure.
max-include-countinteger64Maximum number of included or imported templates per closure.
max-include-depthinteger16Maximum include and extends nesting depth.
max-template-sizeinteger (bytes)1048576 (1 MiB)Maximum size of a single template file.
reload-timeout-msinteger (ms)5000Wall-clock budget for a full reload build.

Zero values are rejected. The block uses deny_unknown_fields, so a typo is caught at load.

[beans]

Named beans are WASM plugins exposed to routes as lookup targets. Each bean is keyed by name and carries a plugin path plus an optional config map and WASM limits.

[beans.auth]
plugin = "my-auth"

[beans.auth.config]
api_key = "${env:API_KEY}"

[beans.auth.limits]
timeout-secs = 600
FieldTypeDefaultDescription
pluginstring(required)Plugin identifier or .wasm path. Must be non-empty.
configtable{}Key-value pairs passed to the plugin.
limitstableabsentWASM limits. See WASM limits.

WASM limits

WASM limits appear in three places: [beans.<name>.limits], [security.permissions.<name>.limits], and [security.policies.wasm.<name>.limits]. The struct is the same in all three. The fields use kebab-case. Unset fields fall back to the rust-camel runtime default. The defaults are finite: 50 MiB max memory, 10 MB max wasm size, 10 000 max instances, 10 000 max tables.

FieldTypeRuntime defaultDescription
timeout-secsinteger (s)runtime defaultMaximum execution time per guest call.
max-memoryinteger (bytes)52428800 (50 MiB)Maximum linear memory the guest can allocate. Enforced by wasmtime.
max-concurrent-callsintegerruntime defaultMaximum concurrent invocations against this plugin.
max-wasm-sizeinteger (bytes)10485760 (10 MB)Maximum .wasm file size.
allow-call-schemesstringnull (deny all)Comma-separated URI schemes the guest may call. Empty or null fails closed.
max-stream-bytesinteger (bytes)runtime defaultMaximum body bytes streamed between host and guest.
max-instancesinteger10000Maximum core instances per store.
max-tablesinteger10000Maximum tables per store.
max-table-elementsintegerunlimitedMaximum elements per table.

[datasources]

Named datasource pools. Each entry is keyed by a name that routes reference through the datasource URI parameter (for example sql:SELECT * FROM users?datasource=my-db). The block is a map of DatasourceConfig values.

[default.datasources.appdb]
db_url = "sqlite:file:memdb?mode=memory&cache=shared"
max_connections = 5
FieldTypeDefaultDescription
db_urlstring(required)Connection URL. postgresql://, postgres://, and ws:// (SurrealDB) are recognised. Must not be empty.
providerstringnullProvider override. Defaults from the URL scheme.
max_connectionsintegernullMaximum pool size.
min_connectionsintegernullMinimum pool size.
idle_timeout_secsinteger (s)nullIdle connection timeout.
max_lifetime_secsinteger (s)nullMaximum connection lifetime.
ssl_modestringnullTLS mode. Provider-specific values.
ssl_root_certstringnullPath to the root CA.
ssl_certstringnullPath to the client certificate.
ssl_keystringnullPath to the client key.
extratable{}Provider-specific key-value pairs. SurrealDB reads namespace and database from here.

Profile overrides

[default] always applies. A named profile like [production] is selected through CAMEL_PROFILE=production or the loader API. Profile blocks deep-merge on top of [default]. The example below shows a [production] block tightening timeouts and pointing Kafka at the production cluster.

# Shared component defaults live in a separate file so they can be reused
# across deployment configs without duplication.
include = ["config/components.toml"]

[default]
routes = ["routes/**/*.yaml"]
log_level = "INFO"

# Optional supervision configuration
[default.supervision]
max_attempts = 5
initial_delay_ms = 1000
backoff_multiplier = 2.0
max_delay_ms = 60000

# Optional tracing configuration
[default.observability.tracer]
enabled = true
detail_level = "minimal"

[default.observability.tracer.outputs.stdout]
enabled = true
format = "json"

# Development profile - more verbose, local services
[development]
log_level = "DEBUG"

[development.components.http]
allow_internal = true  # Allow internal services in dev

[development.components.kafka]
brokers = "localhost:9092"

# Production profile - stricter settings, remote services
[production]
log_level = "WARN"

[production.components.http]
connect_timeout_ms = 5000   # Faster fail in production
allow_internal = false

[production.components.kafka]
brokers = "prod-kafka:9092"
group_id = "camel-prod"
session_timeout_ms = 60000

The [development] and [production] blocks set a log_level and override shared component defaults. Shared component defaults can also live in a separate file pulled through include. See Configuration for the merge rules and the include order.

Environment variable overrides

A small allowlist of CAMEL_* environment variables overrides specific fields when the runtime calls CamelConfig::from_file_with_env. The allowlist is the security boundary: any CAMEL_* variable not in the list is ignored at load and logged as a warning.

VariableField
CAMEL_TIMEOUT_MStimeout_ms
CAMEL_DRAIN_TIMEOUT_MSdrain_timeout_ms
CAMEL_WATCHwatch
CAMEL_WATCH_DEBOUNCE_MSwatch_debounce_ms
CAMEL_LOG_LEVELlog_level
CAMEL_RUNTIME_JOURNAL_PATHruntime_journal.path
CAMEL_RUNTIME_JOURNAL_DURABILITYruntime_journal.durability
CAMEL_RUNTIME_JOURNAL_COMPACTION_THRESHOLD_EVENTSruntime_journal.compaction_threshold_events
CAMEL_IDEMPOTENT_REPO_PATHidempotent_repo.path
CAMEL_IDEMPOTENT_REPO_DURABILITYidempotent_repo.durability
CAMEL_SUPERVISION_INITIAL_DELAY_MSsupervision.initial_delay_ms
CAMEL_SUPERVISION_MAX_ATTEMPTSsupervision.max_attempts

Cache repo overrides carry a typed contract. String-typed fields receive their raw value verbatim, with no numeric or boolean coercion. Numeric-typed fields parse strictly typed values. Duration fields accept humantime forms with explicit units. A unitless numeric value is rejected at validation with an error naming the required format. An empty value is skipped for the newer scalar variables, so the file or profile value stays effective. Legacy variables receive the raw value, empty or not.

VariableFieldValue classEmpty valueDuration rule
CAMEL_CACHE_REPO_BACKENDcache_repo.backendstring-verbatimraw value (not skipped)
CAMEL_CACHE_REPO_PATHcache_repo.pathstring-verbatimraw value (not skipped)
CAMEL_CACHE_REPO_MAX_CAPACITYcache_repo.max_capacitynumeric-typedraw value (not skipped)
CAMEL_CACHE_REPO_STALE_RETENTIONcache_repo.stale_retentionstring-verbatimraw value (not skipped)humantime units required. Unitless numeric rejected: cache_repo.stale_retention: invalid duration '604800' — use a unit-bearing form such as '7d' or '24h'
CAMEL_CACHE_REPO_MAX_ENTRIEScache_repo.max_entriesnumeric-typedraw value (not skipped)
CAMEL_CACHE_REPO_PAYLOADcache_repo.payloadstring-verbatimskipped (file/profile value stays effective)
CAMEL_CACHE_REPO_PAYLOAD_DIRcache_repo.payload_dirstring-verbatimskipped (file/profile value stays effective)
CAMEL_CACHE_REPO_CACHE_SIZEcache_repo.cache_sizestring-verbatimskipped (file/profile value stays effective)
CAMEL_CACHE_REPO_SWEEP_INTERVALcache_repo.sweep_intervalstring-verbatimskipped (file/profile value stays effective)humantime units required. Unitless numeric rejected: cache_repo.sweep_interval: invalid duration '3600' — use a unit-bearing form such as '7d' or '24h'
CAMEL_CACHE_REPO_MASTER_NAMEcache_repo.master_namestring-verbatimskipped (file/profile value stays effective)
CAMEL_CACHE_REPO_KEY_PREFIXcache_repo.key_prefixstring-verbatimskipped (file/profile value stays effective)
CAMEL_CACHE_REPO_DBcache_repo.dbnumeric-typedskipped (file/profile value stays effective)
CAMEL_CACHE_REPO_SENTINEL_NODEScache_repo.sentinel_nodesCSV listempty list replaces the file value and normalizes to absent on redis

CAMEL_CONFIG_FILE and CAMEL_PROFILE are also read, but outside the allowlist. CAMEL_CONFIG_FILE selects the file path before load. CAMEL_PROFILE selects the profile section.

Note: Connection strings and credentials are outside the allowlist. Set them with ${env:VAR} placeholders in Camel.toml values, never through env overrides. The loader ignores CAMEL_CACHE_REPO_URL, CAMEL_CACHE_REPO_USERNAME, CAMEL_CACHE_REPO_PASSWORD, CAMEL_CACHE_REPO_SENTINEL_USERNAME, and CAMEL_CACHE_REPO_SENTINEL_PASSWORD and logs a warning.

Reference: Config crate