Search code examples
solrsolrcloud

Solr Error: QueryComponent.mergeIds(QueryComponent.java:940) when using invariants in a request handler


I need a search request handler that only return a specific sets of field in a collection, but for security reasons, no one can change what fields to be displayed. (There are some indexed sensitive fields that I don't want anyone access it)

I tried to use invariants in the request handler, and define the list of field there, so I made a handler like this:

   <requestHandler class="solr.SearchHandler" name="/search">
    <lst name="defaults">
        <str name="q">*:*</str>
    </lst>
    <lst name="invariants">
        <str name="fl">content</str>
        <str name="fl">description</str>
    </lst>
  </requestHandler>

However, I get this error when I call the request handler:

{
  "responseHeader":{
    "zkConnected":true,
    "status":500,
    "QTime":4},
  "error":{
    "trace":"java.lang.NullPointerException\r\n\tat org.apache.solr.handler.component.QueryComponent.mergeIds(QueryComponent.java:940)\r\n\tat org.apache.solr.handler.component.QueryComponent.handleRegularResponses(QueryComponent.java:585)\r\n\tat org.apache.solr.handler.component.QueryComponent.handleResponses(QueryComponent.java:564)\r\n\tat org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:423)\r\n\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:177)\r\n\tat org.apache.solr.core.SolrCore.execute(SolrCore.java:2503)\r\n\tat org.apache.solr.servlet.HttpSolrCall.execute(HttpSolrCall.java:710)\r\n\tat org.apache.solr.servlet.HttpSolrCall.call(HttpSolrCall.java:516)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:382)\r\n\tat org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:326)\r\n\tat org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1751)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\r\n\tat org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)\r\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\r\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)\r\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)\r\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\r\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\r\n\tat org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)\r\n\tat org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119)\r\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\r\n\tat org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:335)\r\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\r\n\tat org.eclipse.jetty.server.Server.handle(Server.java:534)\r\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)\r\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)\r\n\tat org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:251)\r\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)\r\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)\r\n\tat org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)\r\n\tat org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)\r\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)\r\n\tat java.lang.Thread.run(Unknown Source)\r\n",
    "code":500}}

Currently I do a workaround to put the fields inside the default instead of invariants. so I made the handler to be like this instead:

<requestHandler class="solr.SearchHandler" name="/search">
    <lst name="defaults">
        <str name="q">*:*</str>
        <str name="fl">content</str>
        <str name="fl">description</str>
    </lst>
  </requestHandler>

This workaround is working, but I don't want that because it's not secure enough. Anyone can help? For additional information, I'm using Solr version 7.2.1, and the collection has 2 shards, 2 replicas.


Solution

  • When you set the fl list to invariant, that means that the internal requests between shards won't be able to override it either. The line triggering your error is:

    resultIds.put(shardDoc.id.toString(), shardDoc);
    

    I'm guessing you'd want to include id in your field list, and probably _version_ and _root_ as well. _version_ have special meaning when it comes to replication and optimistic concurrent update, while _root_ affects child documents.