Found the cause: when an extension which is not in the extension index is installed/upgraded/uninstalled (for example an extension coming from a non searchable repository like Maven Central, or an extension which is not part of what a searchable repository returned), ExtensionInstallListener calls ExtensionIndexStore#updateInstalled, which sends a Solr atomic update. Solr creates the document when an atomic update targets a document which does not exist, so the index ends up with a document containing only the installed/compatible namespaces fields: no extension id, version, repository, etc.
Such a document is then also picked by the indexing job (which lists indexed extensions from the document ids) and can receive compatible namespaces through ExtensionIndexStore#updateCompatible. As soon as it matches a search, it breaks the whole result. For example, the empty "Compatible only" search in the Extensions administration fails with:
java.lang.NullPointerException: key
at org.xwiki.collection.SoftCache.put(SoftCache.java:93)
at org.xwiki.extension.internal.ExtensionFactory.getVersion(ExtensionFactory.java:339)
at org.xwiki.extension.index.internal.ExtensionIndexStore.getExtensionId(ExtensionIndexStore.java:714)
at org.xwiki.extension.index.internal.ExtensionIndexStore.toSolrExtension(ExtensionIndexStore.java:723)
at org.xwiki.extension.index.internal.ExtensionIndexStore.search(ExtensionIndexStore.java:806)
at org.xwiki.extension.index.internal.DefaultExtensionIndex.search(DefaultExtensionIndex.java:99)
The null repositoryId reported in XWIKI-23358 is another symptom of the same incomplete documents.
This message was sent by Atlassian Jira (v9.3.0#930000-sha1:287aeb6)
If image attachments aren't displayed, see this article.