{"record":{"id":"b8c330e5d48e766f","repo":"jaegertracing/jaeger","slug":"indices-s-cannot-use-both-rotation-config-and","errorCode":null,"errorMessage":"indices.%s: cannot use both 'rotation' config and legacy 'date_layout'/'rollover_frequency' fields; use 'rotation.periodic' instead","messagePattern":"indices\\.(.+?): cannot use both 'rotation' config and legacy 'date_layout'/'rollover_frequency' fields; use 'rotation\\.periodic' instead","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/elasticsearch/config/config_rotation.go","lineNumber":132,"sourceCode":"\t}\n\n\ttype rotationEntry struct {\n\t\tname     string\n\t\topts     *IndexOptions\n\t\trotation *RotationConfig\n\t}\n\tentries := []rotationEntry{\n\t\t{\"spans\", &c.Indices.Spans, &c.Indices.Spans.Rotation},\n\t\t{\"services\", &c.Indices.Services, &c.Indices.Services.Rotation},\n\t\t{\"dependencies\", &c.Indices.Dependencies, &c.Indices.Dependencies.Rotation},\n\t\t{\"sampling\", &c.Indices.Sampling, &c.Indices.Sampling.Rotation},\n\t}\n\tfor _, e := range entries {\n\t\tif err := e.rotation.validate(e.name); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif e.rotation.HasRotation() && (e.opts.DateLayout.HasValue() || e.opts.RolloverFrequency.HasValue()) {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"indices.%s: cannot use both 'rotation' config and legacy \"+\n\t\t\t\t\t\"'date_layout'/'rollover_frequency' fields; use 'rotation.periodic' instead\",\n\t\t\t\te.name,\n\t\t\t)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (r *RotationConfig) validate(indexType string) error {\n\tcount := 0\n\tif r.Periodic.HasValue() {\n\t\tcount++\n\t}\n\tif r.ManualRollover.HasValue() {\n\t\tcount++\n\t}","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/elasticsearch/config/config_rotation.go#L114-L150","documentation":"Per-index, the new 'rotation' section and the legacy per-index date_layout/rollover_frequency fields are mutually exclusive. validateRotationConfig iterates each index entry and raises this error if an index has both an active rotation strategy and legacy field overrides, directing users to 'rotation.periodic'.","triggerScenarios":"For any of spans/services/dependencies/sampling indices: e.rotation.HasRotation() is true while e.opts.DateLayout.HasValue() or e.opts.RolloverFrequency.HasValue() during Validate.","commonSituations":"Migrating index templates: new rotation block added but old date_layout/rollover_frequency keys left in the same index section of the YAML.","solutions":["Remove date_layout and rollover_frequency from the indices.<type> section","Express the desired cadence via rotation.periodic instead","Keep one mechanism per index, not both"],"exampleFix":"// before\nindices:\n  spans:\n    date_layout: 2006.01.02\n    rollover_frequency: day\n    rotation:\n      periodic:\n        days: 1\n// after\nindices:\n  spans:\n    rotation:\n      periodic:\n        days: 1","handlingStrategy":"validation","validationCode":"for _, idx := range []struct{name string; r Rotation; opts IndexOptions}{\n    {\"spans\", cfg.Indices.Spans.Rotation, cfg.Indices.Spans.Options},\n} {\n    if idx.r.HasRotation() && (idx.opts.DateLayout.HasValue() || idx.opts.RolloverFrequency.HasValue()) {\n        return fmt.Errorf(\"indices.%s: drop date_layout/rollover_frequency, use rotation.periodic\", idx.name)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One rotation mechanism per index","When adding rotation.periodic, delete legacy date fields in the same edit","Test config with a startup dry-run"],"tags":["elasticsearch","config-validation","index-rotation"],"backgroundTag":"conflicting-config-options","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}