apache/skywalking · critical · ModuleStartException

Record TTL should be at least 2 days, current value is {}

Error message

Record TTL should be at least 2 days, current value is {}

What it means

ModuleStartException thrown by CoreModuleProvider.start() when core.record-data-ttl (records = traces/logs/topN records) is below 2 days. Record storage and the TopN/trace query paths assume at least a 2-day window; the provider aborts startup with the offending value in the message. Checked immediately after the metrics TTL guard and before RecordStreamProcessor.setRecordDataTTL(...) is applied.

Source

Thrown at oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java:396

            this.remoteClientManager = new RemoteClientManager(getManager(), moduleConfig.getRemoteTimeout(),
                                                               moduleConfig.getGRPCSslTrustedCAPath()
            );
        } else {
            this.remoteClientManager = new RemoteClientManager(getManager(), moduleConfig.getRemoteTimeout());
        }
        this.registerServiceImplementation(RemoteClientManager.class, remoteClientManager);

        // Management
        this.registerServiceImplementation(
            UITemplateManagementService.class, new UITemplateManagementService(getManager()));

        if (moduleConfig.getMetricsDataTTL() < 2) {
            throw new ModuleStartException(
                "Metric TTL should be at least 2 days, current value is " + moduleConfig.getMetricsDataTTL());
        }
        setBootingParameter("TTL.metrics", moduleConfig.getMetricsDataTTL());
        if (moduleConfig.getRecordDataTTL() < 2) {
            throw new ModuleStartException(
                "Record TTL should be at least 2 days, current value is " + moduleConfig.getRecordDataTTL());
        }
        setBootingParameter("TTL.record", moduleConfig.getRecordDataTTL());

        final MetricsStreamProcessor metricsStreamProcessor = MetricsStreamProcessor.getInstance();
        metricsStreamProcessor.setL1FlushPeriod(moduleConfig.getL1FlushPeriod());
        metricsStreamProcessor.setStorageSessionTimeout(moduleConfig.getStorageSessionTimeout());
        RecordStreamProcessor.getInstance().setRecordDataTTL(moduleConfig.getRecordDataTTL());
        TopNStreamProcessor.getInstance().setTopNWorkerReportCycle(moduleConfig.getTopNReportPeriod());
        apdexThresholdConfig = new ApdexThresholdConfig(this);
        ApdexMetrics.setDICT(apdexThresholdConfig);
        loggingConfigWatcher = new LoggingConfigWatcher(this);

        WatermarkGRPCInterceptor.create();
        this.watermarkWatcher = new WatermarkWatcher(getManager(),
                                                     moduleConfig.getMaxHeapMemoryUsagePercent(),
                                                     moduleConfig.getMaxDirectMemoryUsage());
    }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Set core.record-data-ttl to at least 2 days (shipped default is 7; often set larger than metrics TTL)
  2. Keep record-data-ttl >= metrics-data-ttl for consistent query behavior
  3. Confirm env-var substitution yields a number >= 2 and restart OAP

Example fix

# before
core:
  record-data-ttl: 1

# after
core:
  record-data-ttl: 7
Defensive patterns

Strategy: validation

Validate before calling

int ttl = Integer.parseInt(System.getenv().getOrDefault("SW_CORE_RECORD_DATA_TTL", "7"));
if (ttl < 2) {
    throw new IllegalStateException("core.record-data-ttl must be >= 2 days, got " + ttl);
}

Prevention

When it happens

Trigger: Setting core.record-data-ttl: 0 or 1 in application.yml, or an env substitution resolving below 2. getRecordDataTTL() < 2 throws.

Common situations: Same as metrics TTL: shortening retention on resource-constrained environments, dropping the key from a trimmed config so a low default applies, or assuming the unit is hours/minutes instead of days.

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/738e17029afddd45. Report an issue: GitHub.