"null cannot be cast to non-null type" creating a detector

I’ve tried all sorts of combinations of things in the UI to create a security analytics detector, but I only ever get this error.

Here’s my process:

  1. Click “create detector”
  2. Enter a name
  3. For the “data source,” I’ve tried doing both specific individual indexes (e.g., arkime_sessions3-20w16) and specifying an index pattern (typing arkime_sessions3-* and hitting Enter to add it as a custom option). I would prefer to use an index pattern. I’m not using data streams at the moment. I’m assuming specifying an index pattern is allowed, as at least from the Detector APIs documentation inputs.detector_input.indices says “The log data source used for the detector, which can be either an index name or index pattern. Currently, only one entry is supported with plans to support multiple indexes in a future release. Required.”. I am only entering one index pattern.
  4. Select “Network” for the log type
  5. For “Selected detection rules” I’ve tried enabling all rules, enabling only one rule, doesn’t seem to make a difference.
  6. For “Field Mapping (optional)” I’ve gone through and defined mappings for all of the fields I can. There are two fields that are still showing up as “available” because I don’t have fields for those specific ones, but I’ve mapped all the rest of those. I’m assuming this is okay as it’s optional, anyway? I know that the field mapping section is at last reading the index pattern I’ve specified, because thie list of fields available for mapping changes when I put it in (vs., say, trying it with some bogus value or another index pattern).
  7. Threat intelligence feeds: I’ve tried with it both checked and unchecked, doesn’t seem to affect the error I’m getting.
  8. Schedule, leaving at the default of 1 minute.
  9. Click next to proceed to triggers
  10. I’m just leaving the defaults for triggers (“Trigger 1”, “All rules, All Severities, All Tags”, “1 (Highest)”). I’m not using notifications.
  11. click “create detector”

Results:

an error pops up with:

Create detector failed.

[security_analytics_exception] null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>

Output in the terminal looks like this (EDIT: see my update in the next comment for output from v2.17.1).

So I’m not sure what’s going on here. The first line of the error says some stuff about “older index templates” and patterns but I don’t know what it’s trying to tell me.

I’ve googled this error and seen it mentioned other places but never with any resolution.

I saw the 2.17.1 had some fixes for security analytics and updated, but it is still the same issue in that release as well.

Here’s the output of both my OpenSearch and OpenSearch Dashboards containers:

opensearch-1          | [2024-10-07T14:40:36,318][ERROR][o.o.s.t.TransportIndexDetectorAction] [opensearch] PERF_DEBUG_SAP: Fetching alias path pairs to construct rule_field_names
dashboards-1          | Security Analytics - DetectorsService - createDetector: StatusCodeError: [security_analytics_exception] null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
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:529:35)
dashboards-1          |     at IncomingMessage.emit (node:domain:489:12)
dashboards-1          |     at endReadableNT (node:internal/streams/readable:1400:12)
dashboards-1          |     at processTicksAndRejections (node:internal/process/task_queues:82:21) {
dashboards-1          |   status: 500,
dashboards-1          |   displayName: 'InternalServerError',
dashboards-1          |   path: '/_plugins/_security_analytics/detectors',
dashboards-1          |   query: {},
dashboards-1          |   body: {
dashboards-1          |     error: {
dashboards-1          |       root_cause: [Array],
dashboards-1          |       type: 'security_analytics_exception',
dashboards-1          |       reason: 'null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>',
dashboards-1          |       caused_by: [Object]
dashboards-1          |     },
dashboards-1          |     status: 500
dashboards-1          |   },
dashboards-1          |   statusCode: 500,
dashboards-1          |   response: '{"error":{"root_cause":[{"type":"security_analytics_exception","reason":"null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>"}],"type":"security_analytics_exception","reason":"null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>","caused_by":{"type":"exception","reason":"org.opensearch.commons.alerting.util.AlertingException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>"}},"status":500}',
dashboards-1          |   toString: [Function (anonymous)],
dashboards-1          |   toJSON: [Function (anonymous)]
dashboards-1          | }
opensearch-1          | [2024-10-07T14:40:38,125][ERROR][o.o.a.t.TransportIndexMonitorAction] [opensearch] failed to index doc level queries monitor zi9sZ5IBFQb7rt9T0kWQ. deleting monitor
opensearch-1          | java.lang.NullPointerException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
opensearch-1          |     at org.opensearch.alerting.util.DocLevelMonitorQueries.traverseMappingsAndUpdate(DocLevelMonitorQueries.kt:228) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at org.opensearch.alerting.util.DocLevelMonitorQueries.traverseMappingsAndUpdate(DocLevelMonitorQueries.kt:228) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at org.opensearch.alerting.util.DocLevelMonitorQueries.traverseMappingsAndUpdate(DocLevelMonitorQueries.kt:228) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at org.opensearch.alerting.util.DocLevelMonitorQueries.getAllConflictingFields(DocLevelMonitorQueries.kt:603) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at org.opensearch.alerting.util.DocLevelMonitorQueries.indexDocLevelQueries(DocLevelMonitorQueries.kt:280) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler.indexDocLevelMonitorQueries(TransportIndexMonitorAction.kt:605) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler.access$indexDocLevelMonitorQueries(TransportIndexMonitorAction.kt:268) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler$indexDocLevelMonitorQueries$1.invokeSuspend(TransportIndexMonitorAction.kt) ~[opensearch-alerting-2.17.1.0.jar:2.17.1.0]
opensearch-1          |     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) [kotlin-stdlib-1.8.21.jar:1.8.21-release-380(1.8.21)]
opensearch-1          |     at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233) [kotlinx-coroutines-core-1.1.1.jar:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) [kotlinx-coroutines-core-1.1.1.jar:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) [kotlinx-coroutines-core-1.1.1.jar:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742) [kotlinx-coroutines-core-1.1.1.jar:?]
opensearch-1          | [2024-10-07T14:40:38,155][ERROR][o.o.c.a.u.AlertingException] [opensearch] Alerting error: java.lang.NullPointerException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
opensearch-1          | [2024-10-07T14:40:38,156][ERROR][o.o.s.t.TransportIndexDetectorAction] [opensearch] exception:
opensearch-1          | org.opensearch.commons.alerting.util.AlertingException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
opensearch-1          |     at org.opensearch.commons.alerting.util.AlertingException$Companion.wrap(AlertingException.kt:70) ~[?:?]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler.indexMonitor(TransportIndexMonitorAction.kt:573) ~[?:?]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler.access$indexMonitor(TransportIndexMonitorAction.kt:268) ~[?:?]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler$indexMonitor$1.invokeSuspend(TransportIndexMonitorAction.kt) ~[?:?]
opensearch-1          |     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742) ~[?:?]
opensearch-1          | Caused by: java.lang.Exception: java.lang.NullPointerException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
opensearch-1          |     ... 9 more
opensearch-1          | [2024-10-07T14:40:38,157][ERROR][o.o.s.u.SecurityAnalyticsException] [opensearch] Security Analytics error:
opensearch-1          | org.opensearch.commons.alerting.util.AlertingException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
opensearch-1          |     at org.opensearch.commons.alerting.util.AlertingException$Companion.wrap(AlertingException.kt:70) ~[?:?]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler.indexMonitor(TransportIndexMonitorAction.kt:573) ~[?:?]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler.access$indexMonitor(TransportIndexMonitorAction.kt:268) ~[?:?]
opensearch-1          |     at org.opensearch.alerting.transport.TransportIndexMonitorAction$IndexMonitorHandler$indexMonitor$1.invokeSuspend(TransportIndexMonitorAction.kt) ~[?:?]
opensearch-1          |     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:233) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60) ~[?:?]
opensearch-1          |     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742) ~[?:?]
opensearch-1          | Caused by: java.lang.Exception: java.lang.NullPointerException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
opensearch-1          |     ... 9 more
opensearch-1          | [2024-10-07T14:40:38,159][WARN ][r.suppressed             ] [opensearch] path: /_plugins/_security_analytics/detectors, params: {}
opensearch-1          | org.opensearch.securityanalytics.util.SecurityAnalyticsException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>
opensearch-1          |     at org.opensearch.securityanalytics.util.SecurityAnalyticsException.wrap(SecurityAnalyticsException.java:68) ~[?:?]
opensearch-1          |     at org.opensearch.securityanalytics.util.SecurityAnalyticsException.wrap(SecurityAnalyticsException.java:43) ~[?:?]
opensearch-1          |     at org.opensearch.securityanalytics.transport.TransportIndexDetectorAction$AsyncIndexDetectorsAction.lambda$finishHim$0(TransportIndexDetectorAction.java:1757) ~[?:?]
opensearch-1          |     at org.opensearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:74) [opensearch-2.17.1.jar:2.17.1]
opensearch-1          |     at org.opensearch.action.ActionRunnable$2.doRun(ActionRunnable.java:89) ~[opensearch-2.17.1.jar:2.17.1]
opensearch-1          |     at org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:1005) [opensearch-2.17.1.jar:2.17.1]
opensearch-1          |     at org.opensearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:52) [opensearch-2.17.1.jar:2.17.1]
opensearch-1          |     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) [?:?]
opensearch-1          |     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) [?:?]
opensearch-1          |     at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
opensearch-1          | Caused by: java.lang.Exception: org.opensearch.commons.alerting.util.AlertingException: null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any>

So I spun up a totally vanilla opensearch dashboards instance with the default demo sample data and of course didn’t run into the error. So as I’m working on trying to narrow it down, what do I need to look at? The index templates for my data, probably? Is there any way I can get some debug information about what column(s) null cannot be cast to non-null type kotlin.collections.MutableMap<kotlin.String, kotlin.Any> refers to?

After more playing around with it this morning, I’ve been editing my index templates and am narrowing in. My index templates are using composable templates. I was able to get the operation to create the detector to work by removing my entire composed_of section. So either it’s something general with composable templates, or it’s something specific with one of my inclusions. If it’s the latter, I’m going to do a binary search and see if I can pinpoint what is specifically the problem.

hey @tlacuache - good to see you on here again.

@eirsep @sbcd90 @scrawfor - any ideas for Seth? thanks

1 Like

Hi @tlacuache, Security Analytics Detectors are compatible only with Index Aliases, not Index Patterns. To resolve this issue, you can configure an Index Alias that points to the correct write index (refer to Index aliases - OpenSearch Documentation). Additionally, set up an ISM rollover policy to periodically update the index alias.

If the problem persists, check if there are any field alias mappings (Alias - OpenSearch Documentation) in the current write index’s mappings of the index alias.

1 Like

Thanks for the response, @sbcd90 and @kris! As I described earlier, though, I’m running into the exact same problem when choosing a single index by name from the picker. I assume that is supported, even though it’s not an alias?

I don’t have any field alias mappings that I’m aware of, but I’ll double check. Like I said in my last comment, I was able to get it to work without giving me the error as I removed elements from my composable template definition. Next week I’m going to work on boiling the whole thing down to a more easily reproducible and minimal example (without using an index pattern, thanks for that info) and report back here.

thank you @sbcd90 - looking forward to hearing what you find next week @tlacuache