Trouble with mappings, detectors, and alerts

Still pretty much a mess with v3.2.0.

I try to create a detector with an index alias, and get this:

opensearch-1         | [2025-08-21T19:55:36,956][ERROR][o.o.s.u.SecurityAnalyticsException] [opensearch] Security Analytics error:
opensearch-1         | java.lang.IllegalStateException: Can't upsert index template for concrete index!
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.IndexTemplateManager.upsertIndexTemplateWithAliasMappings(IndexTemplateManager.java:103) [opensearch-security-analytics-3.2.0.0.jar:3.2.0.0]
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.MapperService$1$1.onResponse(MapperService.java:107) [opensearch-security-analytics-3.2.0.0.jar:3.2.0.0]
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.MapperService$1$1.onResponse(MapperService.java:93) [opensearch-security-analytics-3.2.0.0.jar:3.2.0.0]
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.MapperService$2.onResponse(MapperService.java:134) [opensearch-security-analytics-3.2.0.0.jar:3.2.0.0]
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.MapperService$2.onResponse(MapperService.java:131) [opensearch-security-analytics-3.2.0.0.jar:3.2.0.0]
opensearch-1         | 	at org.opensearch.action.support.GroupedActionListener.onResponse(GroupedActionListener.java:81) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.MapperService$3.onResponse(MapperService.java:216) [opensearch-security-analytics-3.2.0.0.jar:3.2.0.0]
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.MapperService$3.onResponse(MapperService.java:208) [opensearch-security-analytics-3.2.0.0.jar:3.2.0.0]
opensearch-1         | 	at org.opensearch.action.support.TransportAction$1.onResponse(TransportAction.java:115) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.support.TransportAction$1.onResponse(TransportAction.java:109) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.support.RetryableAction$RetryingListener.onResponse(RetryableAction.java:183) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.core.action.ActionListener$2.onResponse(ActionListener.java:108) [opensearch-core-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.admin.indices.mapping.put.TransportPutMappingAction$1.onResponse(TransportPutMappingAction.java:191) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.admin.indices.mapping.put.TransportPutMappingAction$1.onResponse(TransportPutMappingAction.java:187) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.metadata.MetadataMappingService$1.onAllNodesAcked(MetadataMappingService.java:385) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.service.ClusterManagerService$SafeAckedClusterStateTaskListener.onAllNodesAcked(ClusterManagerService.java:740) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.service.ClusterManagerService$AckCountDownListener.finish(ClusterManagerService.java:875) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.service.ClusterManagerService$AckCountDownListener.onNodeAck(ClusterManagerService.java:866) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.service.ClusterManagerService$DelegatingAckListener.onNodeAck(ClusterManagerService.java:788) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.coordination.Coordinator$CoordinatorPublication$4$1.onSuccess(Coordinator.java:1830) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.service.ClusterApplierService$SafeClusterApplyListener.onSuccess(ClusterApplierService.java:718) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.service.ClusterApplierService.runTask(ClusterApplierService.java:528) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.cluster.service.ClusterApplierService$UpdateTask.run(ClusterApplierService.java:212) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:916) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.PrioritizedOpenSearchThreadPoolExecutor$TieBreakingPrioritizedRunnable.runAndClean(PrioritizedOpenSearchThreadPoolExecutor.java:299) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.PrioritizedOpenSearchThreadPoolExecutor$TieBreakingPrioritizedRunnable.run(PrioritizedOpenSearchThreadPoolExecutor.java:262) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1095) [?:?]
opensearch-1         | 	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:619) [?:?]
opensearch-1         | 	at java.base/java.lang.Thread.run(Thread.java:1447) [?:?]

Or, for another rule type, this:

dashboards-1         | Security Analytics - IndexService - createAliases: StatusCodeError: [illegal_argument_exception] The provided expression [malcolm_network] matches an alias, specify the corresponding concrete indices instead.
dashboards-1         |     at respond (/usr/share/opensearch-dashboards/node_modules/elasticsearch/src/lib/transport.js:349:15)
dashboards-1         |     at checkRespForFailure (/usr/share/opensearch-dashboards/node_modules/elasticsearch/src/lib/transport.js:306:7)
dashboards-1         |     at HttpConnector.<anonymous> (/usr/share/opensearch-dashboards/node_modules/elasticsearch/src/lib/connectors/http.js:173:7)
dashboards-1         |     at IncomingMessage.wrapper (/usr/share/opensearch-dashboards/node_modules/lodash/lodash.js:4991:19)
dashboards-1         |     at IncomingMessage.emit (node:events:530:35)
dashboards-1         |     at endReadableNT (node:internal/streams/readable:1698:12)
dashboards-1         |     at processTicksAndRejections (node:internal/process/task_queues:82:21) {
dashboards-1         |   status: 400,
dashboards-1         |   displayName: 'BadRequest',
dashboards-1         |   path: '/_aliases',
dashboards-1         |   query: {},
dashboards-1         |   body: {
dashboards-1         |     error: {
dashboards-1         |       root_cause: [Array],
dashboards-1         |       type: 'illegal_argument_exception',
dashboards-1         |       reason: 'The provided expression [malcolm_network] matches an alias, specify the corresponding concrete indices instead.'
dashboards-1         |     },
dashboards-1         |     status: 400
dashboards-1         |   },
dashboards-1         |   statusCode: 400,
dashboards-1         |   response: '{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"The provided expression [malcolm_network] matches an alias, specify the corresponding concrete indices instead."}],"type":"illegal_argument_exception","reason":"The provided expression [malcolm_network] matches an alias, specify the corresponding concrete indices instead."},"status":400}',
dashboards-1         |   toString: [Function (anonymous)],
dashboards-1         |   toJSON: [Function (anonymous)]
dashboards-1         | }

I try it using index patterns and get:

opensearch-1         | org.opensearch.securityanalytics.util.SecurityAnalyticsException: Validation Failed: 1: Index patterns are not supported for doc level monitors.;
opensearch-1         | 	at org.opensearch.securityanalytics.util.SecurityAnalyticsException.wrap(SecurityAnalyticsException.java:72) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction$AsyncIndexDetectorsAction.lambda$finishHim$0(TransportIndexDetectorAction.java:1788) ~[?:?]
opensearch-1         | 	at org.opensearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:74) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.ActionRunnable$2.doRun(ActionRunnable.java:89) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:975) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:52) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1095) [?:?]
opensearch-1         | 	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:619) [?:?]
opensearch-1         | 	at java.base/java.lang.Thread.run(Thread.java:1447) [?:?]
opensearch-1         | Caused by: org.opensearch.action.ActionRequestValidationException: Validation Failed: 1: Index patterns are not supported for doc level monitors.;
opensearch-1         | 	at org.opensearch.commons.alerting.action.IndexMonitorRequest.validate(IndexMonitorRequest.kt:57) ~[?:?]
opensearch-1         | 	at org.opensearch.action.support.TransportAction.execute(TransportAction.java:179) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.support.TransportAction.execute(TransportAction.java:109) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.transport.client.node.NodeClient.executeLocally(NodeClient.java:113) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.transport.client.node.NodeClient.doExecute(NodeClient.java:100) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.transport.client.support.AbstractClient.execute(AbstractClient.java:501) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.commons.alerting.AlertingPluginInterface.indexMonitor(AlertingPluginInterface.kt:59) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction$2.onResponse(TransportIndexDetectorAction.java:346) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction$2.onResponse(TransportIndexDetectorAction.java:275) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction.addThreatIntelBasedDocLevelQueries(TransportIndexDetectorAction.java:835) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction.createMonitorFromQueries(TransportIndexDetectorAction.java:275) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction$AsyncIndexDetectorsAction.upsertMonitorQueries(TransportIndexDetectorAction.java:1658) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction$AsyncIndexDetectorsAction$9.onResponse(TransportIndexDetectorAction.java:1644) ~[?:?]
opensearch-1         | 	at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction$AsyncIndexDetectorsAction$9.onResponse(TransportIndexDetectorAction.java:1622) ~[?:?]
opensearch-1         | 	at org.opensearch.action.support.TransportAction$1.onResponse(TransportAction.java:115) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.support.TransportAction$1.onResponse(TransportAction.java:109) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.securityanalytics.mapper.MapperService$7.lambda$onResponse$0(MapperService.java:422) ~[?:?]
opensearch-1         | 	at org.opensearch.core.action.ActionListener$1.onResponse(ActionListener.java:82) ~[opensearch-core-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.securityanalytics.logtype.LogTypeService.lambda$getRequiredFieldsForAllLogTypes$1(LogTypeService.java:770) ~[?:?]
opensearch-1         | 	at org.opensearch.core.action.ActionListener$3.onResponse(ActionListener.java:132) ~[opensearch-core-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.securityanalytics.logtype.LogTypeService.lambda$getAllFieldMappings$0(LogTypeService.java:406) ~[?:?]
opensearch-1         | 	at org.opensearch.core.action.ActionListener$3.onResponse(ActionListener.java:132) ~[opensearch-core-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.support.TransportAction$1.onResponse(TransportAction.java:115) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.support.TransportAction$1.onResponse(TransportAction.java:109) [opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.ubi.UbiActionFilter$1.onResponse(UbiActionFilter.java:110) ~[?:?]
opensearch-1         | 	at org.opensearch.ubi.UbiActionFilter$1.onResponse(UbiActionFilter.java:91) ~[?:?]
opensearch-1         | 	at org.opensearch.search.pipeline.PipelinedRequest.lambda$transformResponseListener$0(PipelinedRequest.java:47) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.core.action.ActionListener$1.onResponse(ActionListener.java:82) ~[opensearch-core-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.core.action.ActionListener$5.onResponse(ActionListener.java:268) ~[opensearch-core-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.AbstractSearchAsyncAction.sendSearchResponse(AbstractSearchAsyncAction.java:795) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.ExpandSearchPhase.run(ExpandSearchPhase.java:132) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.SearchPhase.recordAndRun(SearchPhase.java:62) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.AbstractSearchAsyncAction.executePhase(AbstractSearchAsyncAction.java:512) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.AbstractSearchAsyncAction.executeNextPhase(AbstractSearchAsyncAction.java:479) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.FetchSearchPhase.moveToNextPhase(FetchSearchPhase.java:300) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.FetchSearchPhase.lambda$innerRun$0(FetchSearchPhase.java:138) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.FetchSearchPhase.innerRun(FetchSearchPhase.java:150) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.action.search.FetchSearchPhase$1.doRun(FetchSearchPhase.java:122) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:52) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.threadpool.TaskAwareRunnable.doRun(TaskAwareRunnable.java:78) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:52) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	at org.opensearch.common.util.concurrent.TimedRunnable.doRun(TimedRunnable.java:59) ~[opensearch-3.2.0.jar:3.2.0]
opensearch-1         | 	... 5 more

So to summarize, depending on what I try:

  • Can't upsert index template for concrete index!
  • The provided expression … matches an alias, specify the corresponding concrete indices instead.
  • Index patterns are not supported for doc level monitors.

You can understand the frustration, I hope?

I’m happy to provide a VM, script/playbook, whatever is needed if somebody wants to look at this.