jaegertracing/jaeger · error
ILM/ISM policy %s doesn't exist. Please create it and re-run
Error message
ILM/ISM policy %s doesn't exist. Please create it and re-run init
What it means
The rollover init action verifies that the configured ILM (Elasticsearch) or ISM (OpenSearch) policy exists before creating rollover aliases and indices. If the policy lookup succeeds but reports the policy missing, this actionable error is returned. Unlike other errors it is not wrapping a transport failure — it is a deliberate existence check.
Source
Thrown at cmd/es-rollover/app/init/action.go:33
// Action holds the configuration and clients for init action
type Action struct {
Config Config
IndicesClient esclient.IndexAPI
ILMClient esclient.IndexManagementLifecycleAPI
}
// Do the init action
func (c Action) Do() error {
ctx := context.TODO()
if c.Config.UseILM {
// Every supported backend provides lifecycle management (ILM on
// Elasticsearch, ISM on OpenSearch), so no capability check is needed.
policyExist, err := c.ILMClient.Exists(ctx, c.Config.ILMPolicyName)
if err != nil {
return err
}
if !policyExist {
return fmt.Errorf("ILM/ISM policy %s doesn't exist. Please create it and re-run init", c.Config.ILMPolicyName)
}
}
rolloverIndices := app.RolloverIndices(c.Config.Archive, c.Config.SkipDependencies, c.Config.AdaptiveSampling, c.Config.Config.IndexPrefix)
for _, indexName := range rolloverIndices {
if err := c.init(ctx, indexName); err != nil {
return err
}
}
return nil
}
func createIndexIfNotExist(ctx context.Context, c esclient.IndexAPI, index string) error {
exists, err := c.IndexExists(ctx, index)
if err != nil {
return err
}
if exists {
return nilView on GitHub (pinned to 806f444784)
Solutions
- Run the Jaeger init command (e.g. `es-rollover init` counterpart that installs the policy / `jaeger-elasticsearch-init`) to create the policy first.
- Check the policy name flag matches an existing policy (GET _ilm/policy or _plugins/_ism/policies).
- Verify the credentials allow reading ILM/ISM policies.
- Re-run `es-rollover init` after the policy exists, as the message instructs.
Example fix
// before ./es-rollover init $ES_URL # policy jaeger-ilm-policy absent // after curl -X PUT $ES_URL/_ilm/policy/jaeger-ilm-policy -d @policy.json ./es-rollover init $ES_URL
Defensive patterns
Strategy: validation
Validate before calling
policy := "jaeger-ilm-policy"
resp, err := http.Get(esURL + "/_ilm/policy/" + policy)
if err != nil || resp.StatusCode == 404 {
return fmt.Errorf("policy %s missing; run init first", policy)
}
resp.Body.Close() Try / catch
if err := action.Do(); err != nil {
if strings.Contains(err.Error(), "doesn't exist") {
// provision the ILM/ISM policy, then re-run init
}
return err
} Prevention
- Always run the Jaeger init step on a fresh Elasticsearch cluster.
- Keep the ILM policy name flag consistent across deployments.
- Verify policy existence with GET _ilm/policy (or ISM equivalent) in CI.
- Ensure the ES user can read ILM/ISM policies.
When it happens
Trigger: Running `es-rollover init` when the ILM/ISM policy named by --ilm-policy-name (or default jaeger-ilm-policy / jaeger-ism-policy) was never created in the cluster, or Exists() returns false because the caller lacks permission to see it.
Common situations: Fresh Elasticsearch cluster where the separate `jaeger init` step that installs the policy was skipped; policy name mismatch between the flag and what was created; OpenSearch cluster still on a path where the policy was never provisioned; restricted user who cannot read the policy.
Related errors
- file must begin with '['
- max spans count reached
- empty configuration
- at least one storage backend is required
- cannot assign unique span ID, too many spans in the trace
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/b6a6f989c74af963.
Report an issue: GitHub.