Major Changes in Solr 10

Solr 10.0 is a major new release of Solr.

This page highlights the most important changes including new features and changes in default behavior as well as previously deprecated features that have now been removed.

Solr 10 Upgrade Planning

Before starting an upgrade to this version of Solr, please be sure to review all information about changes from the version you are currently on up to this one, to include the minor version number changes as well. For example, if you are currently using Solr 9.1, you should review changes made in all subsequent 9.x releases in addition to the 10.0-specific changes on this page.

Users planning their upgrade process should be aware of a change introduced in Solr 9.10 which is especially relevant to Solr 10 and beyond. By default, starting in 9.10 SolrCloud nodes will now fail to start if their major.minor version (e.g. 9.10) is lower than the highest version found elsewhere in the SolrCloud cluster. The intention of this change is to allow Solr to support rolling upgrades but not rolling downgrades spanning a major version. This compatibility safeguard can be disabled via the environment variable "SOLR_CLOUD_DOWNGRADE_ENABLED".

System Requirements

Solr 10.0 requires at least Java 21, while SolrJ 10.0 requires at least Java 17.

Solr 10.0

Solr Jetty parameters

The previous SOLR_JETTY_HOST environment variable and -Dsolr.jetty.host System Property are deprecated and will be removed in a future release. Please update your configuration to use SOLR_HOST_BIND and -Dsolr.host.bind instead.

The previous SOLR_HOST and 'host' are deprecated and now use SOLR_HOST_ADVERTISE and solr.host.advertise.

The previous jetty.port is deprecated and now use solr.port.listen.

Solr CLI and Scripts

The Solr CLI has gone through some significant renovations to reduce technical debt, and now functions more consistently and predictably. Most notably, "long-options" now use double-dashes per Unix style conventions., e.g. --help instead of -help. Users are urged to review all use of the bin/solr command in their automation, scripts, and documentation to ensure that the correct options are being used.

Some key changes that users may encounter are:

  • Commands that interact with Solr now all use --solr-url (or -s) plus a --name (or -c) to specify the Solr to interact with.

  • -z/--zk-host is now supported across all bin/solr tools as an alternative to -s/--solr-url.

  • bin/solr now allows users to specific basic auth credentials via the -u/--credentials option, supplementing the previous SOLR_AUTHENTICATION_OPTS-based support.

  • Some short and single-letter options have been removed to avoid conflicts or in favor to other options.

To learn about the updated options in each CLI tool, use the --help option or look up the tool in the documentation.

Additionally, the bin/solr delete command no longer deletes a configset when you delete a collection. Previously if you deleted a collection, it would also delete it’s associated configset if it was the only user of it. Now you have to explicitly provide a --delete-config option to delete the configsets. This decouples the lifecycle of a configset from that of a collection.

Several scripts formerly provided with Solr have been removed, including bin/post, bin/postlogs, and zkcli.sh. Users should instead rely on bin/solr post and bin/solr zk as appropriate.

SolrJ

  • Starting in 10, the Maven POM for SolrJ does not refer to SolrJ modules like ZooKeeper. If you require such functionality, you need to add additional dependencies.

  • Classes using Jetty HttpClient have been moved to a new package org.apache.solr.solrj.jetty. To use them from your application, you need to include the new solr-solrj-jetty artifact. The following classes were renamed with some refactorings: Http2SolrClient to HttpJettySolrClient, ConcurrentUpdateHttp2SolrClient to ConcurrentUpdateJettySolrClient, LBHttp2SolrClient to LBJettySolrClient. CloudHttp2SolrClient.Builder has moved to CloudSolrClient; users should generally have no need to refer to CloudHttp2SolrClient or any class/member with "http2" in it. The builder will check if Jetty HttpClient is available and use that, otherwise fallback on a JDK based HttpClient. CloudJettySolrClient is new, proving an explicit option. The system property solr.solrj.http.jetty.customizer (formerly solr.httpclient.builder.factory) can configure a HttpJettySolrClient. The only built-in implementation is org.apache.solr.client.solrj.jetty.PreemptiveBasicAuthClientCustomizer, renamed from PreemptiveBasicAuthClientCustomizer.

  • SolrClient implementations that rely on "base URL" strings now only accept "root" URL paths (i.e. URLs that end in "/solr"). Users who previously relied on collection-specific URLs to avoid including the collection name with each request can instead achieve this by specifying a "default collection" using the withDefaultCollection method available on most SolrClient Builders.

  • Minimum Java version for SolrJ 10.x is Java 17.

  • Deprecate CloudSolrClient’s ZooKeeper Hosts constructor. Users are encouraged to supply Solr URLs instead of communicating with ZooKeeper. It’s not likely to be removed before Solr 11.

  • Rename BinaryResponseParser and BinaryRequestWriter including StreamingBinaryResponseParser to JavaBinRequestWriter, JavaBinResponseParser, StreamingJavaBinResponseParser. This makes it clear that they pertain specifically to “JavaBin” rather than binary in general.

  • The deprecated SolrClient implementations based on Apache HttpClient are removed from SolrJ, thus the related dependencies are no longer present.

  • A number of classes moved to different packages to be better organized, including: ShardTerms, DelegatingClusterStateProvider, JavaBinRequestWriter, RoutedAliasTypes, SolrQuery, XMLRequestWriter, JacksonContentWriter, FastStreamingDocsCallback, InputStreamResponse, InputStreamResponseParser, JavaBinResponseParser, ResponseParser, StreamingJavaBinResponseParser, StreamingResponseCallback, XMLResponseParser, JacksonDataBindResponseParser, JsonMapResponseParser, SocketProxy

SolrCloud Overseer

SolrCloud now supports disabling the "Overseer", which is an elected node responsible for processing all cluster administration requests and collection state updates. When disabled, any node that either receives such a request or wishes to do it internally will execute the command. It was possible to disable the Overseer since Solr 9 using undocumented configuration in solr.xml (distributedClusterStateUpdates & distributedCollectionConfigSetExecution) that have since been removed. Now this mode is toggled either with a boolean cluster property overseerEnabled, or an env var SOLR_CLOUD_OVERSEER_ENABLED. In Solr 11, the Overseer might cease to exist, in an effort to simplify SolrCloud and maintenance.

Upgrades: This choice cannot be changed with a rolling upgrade; doing so is highly risky. All nodes in the cluster must always have a consistent understanding of the overseer’s enablement. If using the cluster property toggle, use the bin/solr cluster CLI utility to set it while the cluster is offline. If using the env var; ensure each Solr node is configured to start with the setting set consistently.

When the Overseer is disabled, it is nonetheless still elected, which can be influenced by node roles. If you are using any cluster singleton plugins, they execute on the node elected to be the Overseer.

In general, most users won’t notice a difference. Commands should execute faster without the Overseer. Debugging some SolrCloud problems with the Overseer is more challenging than without since the Overseer is complex (a principal reason for it’s disablement). But the Overseer centralized some processing that results in efficiencies for large clusters in some scenarios. If you have a collection that has many replicas (hundreds), and many are co-located on the same node, then node stops and starts will internally interact with ZooKeeper more. Using minStateByteLenForCompression will help. Creating a replica (either via collection creation or other circumstances) can take more time without the Overseer if these creation commands are delivered to many nodes around the cluster. That can be avoided simply by sending admin requests to a consistent node.

Service Installer

The service installer now installs a systemd startup script instead of an init.d startup script. It is up to the user to uninstall any existing init.d script when upgrading.

SolrCloud Request Routing

HTTP requests to SolrCloud that are for a specific core must be delivered to the node with that core, or else an HTTP 404 Not Found response will occur. Previously, SolrCloud would try too hard scanning the cluster’s state to look for it and internally route/proxy it. If only one node is exposed to a client, and if the client uses the bin/solr export tool, it probably won’t work.

Modern NLP Models from Apache OpenNLP with Solr

Solr now lets you access models encoded in ONNX format, commonly sourced from HuggingFace. The DocumentCategorizerUpdateProcessorFactorythat lets you perform sentiment and other classification tasks on fields. It is available as part of the analysis-extras module.

Vector Search Enhancements

  • The efSearchScaleFactor parameter is now available for the KNN query parser (SOLR-17928). This parameter controls how many candidate vectors are explored during HNSW graph traversal, allowing users to independently tune search accuracy versus the number of results returned. Previously, improving accuracy required increasing topK (which returns more results), but efSearchScaleFactor enables exploring more candidates while still receiving exactly topK results. The efSearch value is calculated internally as efSearchScaleFactor * topK. Default value is 1.0, which means efSearch defaults to topK.

Deprecation Code Removals

  • Several deprecated modules have been removed.

    • jaegertracer-configurator is gone; the new opentelemetry module should be used instead.

    • analytics has been removed

    • hadoop-auth (including the solr.KerberosPlugin class) has been removed

  • OpenTracing libraries were removed and replaced with OpenTelemetry libraries. Any Java agents providing OpenTracing tracers will no longer work. Telemetry tags http.status_code and http.method have been deprecated, newer version of the tags have been added to the span data: http.response.status_code, http.request.method.

  • The sysProp -Dsolr.redaction.system.pattern, which allows users to provide a pattern to match sysProps that should be redacted for sensitive information, has been removed. Please use -Dsolr.hiddenSysProps or the envVar SOLR_HIDDEN_SYS_PROPS instead.

  • The <hiddenSysProps> solr.xml element under <metrics> has been removed. Instead use the <hiddenSysProps> tag under <solr>, which accepts a comma-separated string. Please see -Dsolr.redaction.system.pattern, which allows users to provide a pattern to match sysProps that should be redacted for sensitive information, has been removed. Please use -Dsolr.hiddenSysProps or the envVar SOLR_HIDDEN_SYS_PROPS instead.

  • The node configuration file /solr.xml can no longer be loaded from Zookeeper. Solr startup will fail if it is present.

  • The legacy Circuit Breaker named CircuitBreakerManager is removed. Please use individual Circuit Breaker plugins instead.

  • BlobRepository and BlobHandler have both been removed in favour of the FileStore API implementation (per node stored file). To share resource intensive objects across multiple cores in components you should now use the CoreContainer.getObjectCache approach

  • The language specific Response Writers, which were deprecated in 9.8 in favour of more widely used formats like JSON have been removed. The removed writer types (invoked as part of the wt parameter) include python, ruby, php, and phps.

  • The XLSX Response Writer (wt=xlsx), which was deprecated in 9.10, has been removed. Users needing Excel export functionality should use CSV format (wt=csv) and convert it to Excel format using external tools or libraries.

  • The deprecated support for configuring replication using master/slave terminology is removed. Use leader/follower.

  • Support for the <lib/> directive, which historically could be used in solrconfig.xml to add JARs on a core-by-core basis, was deprecated in 9.8 and has now been removed. Users that need to vary JAR accessibility on a per-core basis can use Solr’s Package Manager. Users who that don’t need to vary JAR access on a per-core basis have several options, including the <sharedLib/> tag supported by solr.xml or manipulation of Solr’s classpath prior to JVM startup.

  • Storing indexes and snapshots in HDFS has been removed. This results in changes to solrconfig.xml and related configuration files and removal of the hdfs module.

  • ExternalFileField field type has been removed.

  • CurrencyField has been removed. Users should migrate to the CurrencyFieldType implementation.

  • The addHttpRequestToContext option in solrconfig.xml has been removed; it’s obsolete. Nowadays, the HTTP request is available via internal APIs: SolrQueryRequest.getHttpSolrCall().getReq().

  • EnumField has been removed. Users should migrate to the EnumFieldType implementation.

  • PreAnalyzedField and PreAnalyzedUpdateProcessor have been removed due to incompatibility with Lucene 10 (SOLR-17839).

  • The ConcurrentMergeScheduler’s autoIOThrottle default changed to false but true may be configured to retain prior behaviour. (SOLR-17631).

  • The TieredMergePolicy’s segmentsPerTier default changed to 8 but 10 may be configured to retain prior behaviour. (SOLR-17917).

  • BlobHandler and the .system collection have been removed in favour of FileStore API. (SOLR-17851).

  • The deprecated transient Solr cores capability has been removed. (SOLR-17932)

  • TikaLanguageIdentifierUpdateProcessor, which was deprecated in 9.10, has been removed. Users should use LangDetectLanguageIdentifierUpdateProcessor or OpenNLPLangDetectUpdateProcessor instead for language detection. (SOLR-17960)

  • LocalTikaExtractionBackend, which was deprecated in 9.10, has been removed. The 'tikaserver' extraction backend is now the only supported backend for the ExtractingRequestHandler, and the default. Users must configure a Tika Server URL via the tikaserver.url parameter. (SOLR-17961)

+NOTE: The previous parse-context-based configuration (parseContext.config) is no longer supported. Tika parser-specific properties must now be configured directly on the Tika Server itself, rather than through Solr configuration. Please refer to the Tika Server documentation for details on how to set these properties.

  • The Prometheus exporter, JMX, SLF4J and Graphite metric reporters have been removed. Users should migrate to using OTLP or the /admin/metrics endpoint with external tools to get metrics to their preferred backend such as the OTEL Collector.

  • The deprecated JaspellLookupFactory suggester implementation has been removed. The default suggester lookup implementation is now FSTLookupFactory, which provides better memory efficiency.

  • SolrInfoMBeanHandler and PluginInfoHandler have been removed

  • The deprecated ManagedSynonymFilterFactory has been removed. Use ManagedSynonymGraphFilterFactory instead with FlattenGraphFilterFactory at index time.

  • The deprecated LowerCaseTokenizer and LowerCaseTokenizerFactory have been removed. These classes were deprecated in Solr 8 and can be replaced by combining LetterTokenizerFactory with LowerCaseFilterFactory.

  • The deprecated 'solrcore.properties` configuration method has been removed. The ability to configure a core via a custom properties file using the core.proprties "property" setting remains.

Security

  • There is no longer a distinction between trusted and untrusted configSets; all configSets are now considered trusted. To ensure security, Solr should be properly protected using authentication and authorization mechanisms, allowing only authorized users with administrative privileges to publish them.

  • stream.file, stream.url, and stream.body params are no longer supported..

Upgrade to Jetty 12.x and Jakarta namespace

Solr upgraded to Jetty 12.x from 10.x as Jetty 10 and 11 have reached end-of-life support. Jetty 12.x requires Java 17 or newer and is fully compatible with Solr’s new minimum requirement of Java 21. This upgrade brings support for modern HTTP protocols and adopts the Jakarta EE 10 namespace. For more details, see https://webtide.com/jetty-12-has-arrived/. This migration marks the point at which Solr no longer includes any JAR with "javax" in it — the Jakarta migration is complete.

OpenTelemetry

Solr 10 has migrated from Dropwizard metrics to OpenTelemetry (OTEL) for observability. This migration provides native Prometheus support, OTLP support, exemplar support for tracing correlation, and native attributes and labels on all metrics.

  • All metrics have been migrated to snake-case metric names instead of dot-delimited format and now natively include attributes/labels.

  • The /admin/metrics API now defaults to Prometheus exposition format and no longer supports XML/JSON/javabin. You can specify wt=prometheus as a parameter for Prometheus format or wt=openmetrics for OpenMetrics exposition format with exemplars support (distributed tracing must be enabled to view exemplars).

  • The metrics API supports filtering by metric name and attributes. See Metrics API Filter for more info.

  • OTLP metrics exporter via gRPC or HTTP is now supported with the OpenTelemetry module. Users can enable the module to push metrics to their preferred OTLP-supported backend.

  • Core renaming and swapping will reset the state of all corresponding core metrics.

Docker

The OS version of the official Docker image and provided Dockerfile has been upgraded to Ubuntu 24 (noble) from Ubuntu 22 (jammy). The Docker base image is eclipse-temurin:25-jre-noble.

Miscellaneous

Solr logs no longer include webapp=/solr and there’s no longer a "webapp" key-value pair in the internal context.

Analysis and Tokenizers

PathHierarchyTokenizer Behavior Change

Due to Lucene 10 changes (https://github.com/apache/lucene/pull/12875), PathHierarchyTokenizer now produces sequential tokens (position increment = 1) instead of overlapping tokens (position increment = 0). This affects ancestor queries that relied on overlapping token matching. Users should test existing queries and update configurations if needed.

  • In Lucene 10, the OrdinalIterator class has been moved from the main lucene-facet module to the lucene-sandbox module. This requires Solr core to now include a dependency on lucene-sandbox to support faceting operations that use this class.

Example configuration change:

<!-- Before: Query-time tokenization for ancestors -->
<fieldType name="ancestor_path" class="solr.TextField">
  <analyzer type="index">
    <tokenizer class="solr.KeywordTokenizerFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/"/>
  </analyzer>
</fieldType>

<!-- After: Index-time tokenization for modern behavior -->
<fieldType name="ancestor_path" class="solr.TextField">
  <analyzer type="index">
    <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/"/>
  </analyzer>
</fieldType>

Attention:

  • The llm module has been renamed to language-models.

  • The HNSW parameters hnswMaxConnections and hnswBeamWidth have been renamed to hnswM and hnswEfConstruction, respectively, so they must be updated accordingly in the schema.xml file.