Configure Telemetry, Logs, Metrics & SSL in Kestra

For the complete documentation index, see llms.txt. For a full content snapshot, see llms-full.txt. Append .md to any kestra.io/docs/* URL for plain Markdown.

Use this page for operational visibility and network-facing configuration.

Observability

Use this section when you need to understand what Kestra emits about itself, not when you are changing task behavior. The settings here are mostly for platform operators and anyone integrating Kestra with monitoring or logging systems.

Configuration areas in this group include:

  • anonymous telemetry
  • logger settings
  • access logs and log formatting
  • metrics and label-based metrics
  • Micronaut HTTP settings

These settings are useful when you need to tune visibility, log volume, request handling, or integration with monitoring platforms.

Anonymous usage reporting is enabled by default. Disable or tune it with:

kestra:
anonymous-usage-report:
enabled: false
kestra:
anonymous-usage-report:
initial-delay: 5m
fixed-delay: 1h

UI usage reporting is configured separately:

kestra:
ui-anonymous-usage-report:
enabled: false

Logs and access logging

There are two different concerns here: application logs and HTTP access logs. Reach for logger.levels when you want to change verbosity inside Kestra, and Micronaut access logging when you want request-by-request HTTP visibility.

Use logger.levels to adjust server log verbosity:

logger:
levels:
io.kestra.core.runners: TRACE
org.apache.kafka: DEBUG

You can also suppress execution-scoped logs globally:

logger:
levels:
execution: 'OFF'
task: 'OFF'
trigger: 'OFF'

Or scope suppression to a specific flow, task, or trigger by appending the flow ID and optionally the task or trigger ID:

logger:
levels:
execution.hello-world: 'OFF'
task.hello-world: 'OFF'
trigger.hello-world: 'OFF'
task.hello-world.log: 'OFF'
trigger.hello-world.schedule: 'OFF'

Micronaut access logging is configured separately:

micronaut:
server:
netty:
access-logger:
enabled: true
logger-name: io.kestra.webserver.access
log-format: "[Date: {}] [Duration: {} ms] [Method: {}] [Url: {}] [Status: {}] [Length: {}] [Ip: {}] [Port: {}]"
exclusions:
- /ui/.+
- /health
- /prometheus

Kestra uses Logback for logging. To use a custom logback.xml, pass it via JAVA_OPTS:

export JAVA_OPTS="-Dlogback.configurationFile=file:/path/to/logback.xml"

GCP structured logging:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<include resource="logback/base.xml" />
<include resource="logback/gcp.xml" />
<root level="WARN">
<appender-ref ref="CONSOLE_JSON_OUT" />
<appender-ref ref="CONSOLE_JSON_ERR" />
</root>
</configuration>

ECS format:

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<include resource="logback/base.xml" />
<include resource="logback/ecs.xml" />
<root level="WARN">
<appender-ref ref="CONSOLE_ECS_OUT" />
<appender-ref ref="CONSOLE_ECS_ERR" />
</root>
</configuration>

Metrics and telemetry exports

These settings are usually enabled with restraint. Metrics are broadly useful, but label-based metrics should stay limited to a small set of low-cardinality dimensions or they become expensive to store and query.

Set a metrics prefix:

kestra:
metrics:
prefix: kestra

Add low-cardinality labels as metric tags:

kestra:
metrics:
labels:
- country
- environment

This creates a tag named label_<key> for each configured label. When an execution does not have a configured label key, the tag value is set to __none__, which keeps the set of tag keys stable and avoids metric series fragmentation.

For example, with country and environment configured, an execution that has country=Germany but no environment label produces:

kestra_executions_total{flow_id="my-flow",namespace_id="default",state="SUCCESS",label_country="Germany",label_environment="__none__"} 1

To collect metrics from other service instances and re-expose them on the webserver’s monitoring endpoint, use sharedServiceInstanceMetrics. Each key is a service type (EXECUTOR, INDEXER, SCHEDULER, WEBSERVER, WORKER) and each value is a list of fully-qualified metric names:

kestra:
metrics:
sharedServiceInstanceMetrics:
WORKER:
- kestra.worker.job.pending
- kestra.worker.job.thread
- kestra.worker.job.running

See Service Instance Metrics for details.

For traces, metrics, and logs exported through OpenTelemetry, use the dedicated OpenTelemetry guide.

Network and HTTP settings

This section matters when Kestra is exposed behind a load balancer, reverse proxy, ingress, or private network boundary. If requests are not arriving with the expected URL, protocol, size limit, or auth behavior, the fix is often here.

Micronaut-backed settings cover:

  • server port
  • SSL
  • timeouts
  • upload size
  • base path
  • host resolution
  • CORS
  • management endpoints

Common examples:

micronaut:
server:
port: 8086
micronaut:
server:
max-request-size: 10GB
multipart:
max-file-size: 10GB
disk: true
read-idle-timeout: 60m
write-idle-timeout: 60m
idle-timeout: 60m
netty:
max-chunk-size: 10MB

Reverse proxy support:

micronaut:
server:
context-path: "kestra-prd"
host-resolution:
host-header: Host
protocol-header: X-Forwarded-Proto

Enable CORS:

micronaut:
server:
cors:
enabled: true

Secure or move management endpoints:

endpoints:
all:
basic-auth:
username: your-user
password: your-password
port: 8084

SSL example:

micronaut:
security:
x509:
enabled: true
ssl:
enabled: true
server:
ssl:
client-authentication: need
key-store:
path: classpath:ssl/keystore.p12
password: ${KEYSTORE_PASSWORD}
type: PKCS12
trust-store:
path: classpath:ssl/truststore.jks
password: ${TRUSTSTORE_PASSWORD}
type: JKS

UI and webserver settings

These settings are lighter-weight than the Micronaut server settings above. Use them when you are customizing the user-facing web experience rather than transport-level HTTP behavior.

The webserver-related configuration also includes:

  • disabling the UI to run the webserver API-only
  • Google Analytics ID
  • additional HTML tags
  • mail server settings
  • security response headers

Examples:

kestra:
webserver:
google-analytics-id: G-XXXXXXXXXX
kestra:
webserver:
html-head:
- "<script>/* custom tag */</script>"

Mail server settings are useful when you need platform emails for invitations and notifications.

Security response headers

Kestra adds browser security response headers to every HTTP response, including error responses (401, 403) and static file responses.

Three headers are enabled by default:

HeaderDefault value
X-Frame-OptionsSAMEORIGIN
X-Content-Type-Optionsnosniff
Referrer-Policystrict-origin-when-cross-origin

Two additional headers are disabled by default:

HeaderWhen emitted
Content-Security-PolicyWhen content-security-policy is set to a non-blank value
Strict-Transport-SecurityWhen strict-transport-security is set and the request arrives at Kestra over HTTPS directly

Each header is added only if not already present in the response.

Configuration reference:

PropertyTypeDefaultDescription
kestra.webserver.security-headers.enabledbooleantrueMaster toggle. When false, the filter is not created and no headers are added.
kestra.webserver.security-headers.frame-optionsstringSAMEORIGINValue for X-Frame-Options. Set to "" to disable this header only.
kestra.webserver.security-headers.content-type-optionsstringnosniffValue for X-Content-Type-Options. Set to "" to disable this header only.
kestra.webserver.security-headers.referrer-policystringstrict-origin-when-cross-originValue for Referrer-Policy. Set to "" to disable this header only.
kestra.webserver.security-headers.content-security-policystring(absent)Value for Content-Security-Policy. Not set unless configured.
kestra.webserver.security-headers.content-security-policy-report-onlybooleanfalseWhen true, the CSP value is sent under Content-Security-Policy-Report-Only instead of Content-Security-Policy. Use this to test a policy before enforcing it.
kestra.webserver.security-headers.strict-transport-securitystring(absent)Value for Strict-Transport-Security. Not set unless configured, and only emitted when Kestra is serving the request over HTTPS directly (see note below).

Enable CSP in report-only mode — report-only sends the policy without blocking any resources, so you can test that your CSP does not break any Kestra UI functionality before switching to enforcement:

kestra:
webserver:
security-headers:
content-security-policy: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' wss:; frame-ancestors 'none'"
content-security-policy-report-only: true

Remove content-security-policy-report-only or set it to false to switch from reporting to enforcement.

Disable an individual header by setting its value to an empty string:

kestra:
webserver:
security-headers:
frame-options: ""

Disable all security headers:

kestra:
webserver:
security-headers:
enabled: false

Disabling the UI (API-only mode)

The bundled web UI is enabled by default. Set kestra.webserver.ui.enabled to false to run the webserver as an API-only service — useful when Kestra is driven entirely through the REST API or fronted by your own application, and you don’t want the UI exposed.

kestra:
webserver:
ui:
enabled: false

When the UI is disabled:

  • requests to /ui/** return 404, and / no longer redirects to the UI;
  • the REST API (/api/v1/**) and health endpoints keep working as usual.

The setting can also be provided through the KESTRA_WEBSERVER_UI_ENABLED environment variable.

Typical use cases

Use this section when you need to:

  • expose Kestra behind a reverse proxy
  • enable HTTPS
  • adjust access log format for GCP or ECS
  • configure Prometheus-style metrics ingestion
  • change management endpoint behavior
  • configure security response headers (CSP, HSTS, framing)

Was this page helpful?