Versions: Opensearch 3.1.0, Dashboards 3.1.0
Describe the issue:
For convenience in using Security Analytics, my project (Malcolm) calls the _security_analytics/mappings
API with this mapping for our network logs:
{
"index_name": "malcolm_network",
"rule_topic": "network",
"partial": true,
"alias_mappings": {
"properties": {
"zeek.x509.certificate.serial": {
"type": "alias",
"path": "zeek.x509.certificate_serial"
},
"service": {
"type": "alias",
"path": "network.protocol"
},
"rejected": {
"type": "alias",
"path": "zeek.dns.rejected"
},
"id.resp_p": {
"type": "alias",
"path": "destination.port"
},
"id.resp_h": {
"type": "alias",
"path": "destination.ip"
},
"id.orig_h": {
"type": "alias",
"path": "source.ip"
},
"Z-flag": {
"type": "alias",
"path": "zeek.dns.Z"
}
}
}
}
It’s not required, but it saves the user from having to map things like id.orig_h
to source.ip
every time, e.g., from these default sigma Network zeek rules.
However, we’ve discovered that when we have this mapping in place, although all the rest of the dashboards seem to work fine, this completely breaks query workbench.
The error looks like this:
opensearch-1 | [2025-08-13T15:46:26,170][ERROR][o.o.s.l.p.RestSqlAction ] [opensearch] 450f1076-0c40-403b-ba67-19eacd5debcd Server side error during query execution
opensearch-1 | java.lang.IllegalStateException: Failed to read mapping for index pattern [[Ljava.lang.String;@3184069c]
opensearch-1 | at org.opensearch.sql.opensearch.client.OpenSearchNodeClient.getIndexMappings(OpenSearchNodeClient.java:97) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.request.system.OpenSearchDescribeIndexRequest.getFieldTypes(OpenSearchDescribeIndexRequest.java:104) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.storage.OpenSearchIndex.getFieldTypes(OpenSearchIndex.java:137) ~[?:?]
opensearch-1 | at org.opensearch.sql.analysis.Analyzer.visitRelation(Analyzer.java:208) ~[?:?]
opensearch-1 | at org.opensearch.sql.analysis.Analyzer.visitRelation(Analyzer.java:137) ~[?:?]
opensearch-1 | at org.opensearch.sql.ast.tree.Relation.accept(Relation.java:69) ~[?:?]
opensearch-1 | at org.opensearch.sql.analysis.Analyzer.visitAggregation(Analyzer.java:338) ~[?:?]
opensearch-1 | at org.opensearch.sql.analysis.Analyzer.visitAggregation(Analyzer.java:137) ~[?:?]
opensearch-1 | at org.opensearch.sql.ast.tree.Aggregation.accept(Aggregation.java:71) ~[?:?]
opensearch-1 | at org.opensearch.sql.analysis.Analyzer.visitProject(Analyzer.java:386) ~[?:?]
opensearch-1 | at org.opensearch.sql.analysis.Analyzer.visitProject(Analyzer.java:137) ~[?:?]
opensearch-1 | at org.opensearch.sql.ast.tree.Project.accept(Project.java:65) ~[?:?]
opensearch-1 | at org.opensearch.sql.analysis.Analyzer.analyze(Analyzer.java:162) ~[?:?]
opensearch-1 | at org.opensearch.sql.executor.QueryService.analyze(QueryService.java:247) ~[?:?]
opensearch-1 | at org.opensearch.sql.executor.QueryService.executeWithLegacy(QueryService.java:164) ~[?:?]
opensearch-1 | at org.opensearch.sql.executor.QueryService.execute(QueryService.java:74) ~[?:?]
opensearch-1 | at org.opensearch.sql.executor.execution.QueryPlan.execute(QueryPlan.java:69) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.executor.OpenSearchQueryManager.lambda$submit$0(OpenSearchQueryManager.java:31) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.executor.OpenSearchQueryManager.lambda$withCurrentContext$1(OpenSearchQueryManager.java:45) ~[?:?]
opensearch-1 | at org.opensearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:916) ~[opensearch-3.1.0.jar:3.1.0]
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.IllegalStateException: Cannot find the path [source.ip] for alias type field [orig_h]
opensearch-1 | at org.opensearch.sql.opensearch.data.type.OpenSearchDataType.lambda$parseMapping$4(OpenSearchDataType.java:146) ~[?:?]
opensearch-1 | at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:986) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.data.type.OpenSearchDataType.parseMapping(OpenSearchDataType.java:140) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.data.type.OpenSearchDataType.of(OpenSearchDataType.java:172) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.data.type.OpenSearchDataType.lambda$parseMapping$3(OpenSearchDataType.java:131) ~[?:?]
opensearch-1 | at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:986) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.data.type.OpenSearchDataType.parseMapping(OpenSearchDataType.java:114) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.mapping.IndexMapping.<init>(IndexMapping.java:32) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.client.OpenSearchNodeClient.lambda$getIndexMappings$2(OpenSearchNodeClient.java:92) ~[?:?]
opensearch-1 | at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:180) ~[?:?]
opensearch-1 | at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) ~[?:?]
opensearch-1 | at java.base/java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet.lambda$entryConsumer$0(Collections.java:1778) ~[?:?]
opensearch-1 | at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1858) ~[?:?]
opensearch-1 | at java.base/java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntrySetSpliterator.forEachRemaining(Collections.java:1803) ~[?:?]
opensearch-1 | at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[?:?]
opensearch-1 | at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?]
opensearch-1 | at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[?:?]
opensearch-1 | at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
opensearch-1 | at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[?:?]
opensearch-1 | at org.opensearch.sql.opensearch.client.OpenSearchNodeClient.getIndexMappings(OpenSearchNodeClient.java:90) ~[?:?]
opensearch-1 | ... 22 more
dashboards-1 | log [15:46:26.175] [info][plugins][queryWorkbenchDashboards] error describeQueryPostInternal
dashboards-1 | log [15:46:26.176] [info][plugins][queryWorkbenchDashboards] StatusCodeError: Internal Server Error
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: 500,
dashboards-1 | displayName: 'InternalServerError',
dashboards-1 | path: '/_plugins/_sql',
dashboards-1 | query: {},
dashboards-1 | body: '{\n' +
dashboards-1 | ' "error": {\n' +
dashboards-1 | ' "reason": "There was internal problem at backend",\n' +
dashboards-1 | ' "details": "Failed to read mapping for index pattern [[Ljava.lang.String;@3184069c]",\n' +
dashboards-1 | ' "type": "IllegalStateException"\n' +
dashboards-1 | ' },\n' +
dashboards-1 | ' "status": 500\n' +
dashboards-1 | '}',
dashboards-1 | statusCode: 500,
dashboards-1 | response: '{\n' +
dashboards-1 | ' "error": {\n' +
dashboards-1 | ' "reason": "There was internal problem at backend",\n' +
dashboards-1 | ' "details": "Failed to read mapping for index pattern [[Ljava.lang.String;@3184069c]",\n' +
dashboards-1 | ' "type": "IllegalStateException"\n' +
dashboards-1 | ' },\n' +
dashboards-1 | ' "status": 500\n' +
dashboards-1 | '}',
dashboards-1 | toString: [Function (anonymous)],
dashboards-1 | toJSON: [Function (anonymous)]
dashboards-1 | }
dashboards-1 | error [15:46:26.067] Error: Internal Server Error
dashboards-1 | at HapiResponseAdapter.toError (/usr/share/opensearch-dashboards/src/core/server/http/router/response_adapter.js:127:19)
dashboards-1 | at HapiResponseAdapter.toHapiResponse (/usr/share/opensearch-dashboards/src/core/server/http/router/response_adapter.js:83:19)
dashboards-1 | at HapiResponseAdapter.handle (/usr/share/opensearch-dashboards/src/core/server/http/router/response_adapter.js:79:17)
dashboards-1 | at Router.handle (/usr/share/opensearch-dashboards/src/core/server/http/router/router.js:175:34)
dashboards-1 | at processTicksAndRejections (node:internal/process/task_queues:95:5)
dashboards-1 | at handler (/usr/share/opensearch-dashboards/src/core/server/http/router/router.js:140:50)
dashboards-1 | at exports.Manager.execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/toolkit.js:60:28)
dashboards-1 | at Object.internals.handler (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/handler.js:46:20)
dashboards-1 | at exports.execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/handler.js:31:20)
dashboards-1 | at Request._lifecycle (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/request.js:371:32)
dashboards-1 | at Request._execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/request.js:281:9)
The specific errors that helped us figured out what’s going on:
opensearch-1 | Caused by: java.lang.IllegalStateException: Cannot find the path [source.ip] for alias type field [orig_h]
opensearch-1 | Caused by: java.lang.IllegalStateException: Cannot find the path [zeek.x509.certificate_serial] for alias type field [serial]
- etc.
Removing this alias mapping restores query workbench functionality.
Is this something I’m doing wrong, or is this a bug in OpenSearch?