This page describes the procedures for upgrading Fess from a previous version to the latest release.
Warning
Important Notes Before Upgrade
Always create a backup before upgrading
It is strongly recommended to validate the upgrade in a test environment first
Services will be stopped during the upgrade, so schedule appropriate maintenance time
Configuration file formats may have changed depending on the version
Supported Versions
This upgrade procedure supports upgrades between the following versions:
Fess 14.x → Fess 15.8
Fess 15.x → Fess 15.8
Important
Fess 14.x supports the OpenSearch 2.x series, while Fess 15.8 supports OpenSearch 3.8.0. Because the OpenSearch plugins for Fess must exactly match the OpenSearch version, upgrading from 14.x also requires a major version upgrade of OpenSearch. See Step 4: Upgrade OpenSearch for details.
Note
When upgrading from older versions (13.x or earlier), a phased upgrade may be necessary. For details, check the release notes.
Pre-Upgrade Preparation
Verify Version Compatibility
Verify the compatibility between the upgrade target version and the current version.
System Requirements - Fess 15.8 system requirements (Java and OpenSearch versions)
Plan Downtime
The upgrade process requires system shutdown. Plan downtime considering the following:
Backup time: 10 minutes to several hours (depending on data volume)
Upgrade time: 10 to 30 minutes
Verification time: 30 minutes to 1 hour
Reserve time: 30 minutes
Recommended Maintenance Time: Total 2 to 4 hours
Step 1: Data Backup
Back up all data before upgrading.
Configuration Data Backup
Backup from Admin Screen
Log in to the admin screen and click “System Info” → “Backup”.
The backup page lists the following configuration data as individual items. Click each row to download it (these are individual files per item, not a single ZIP; there is no bulk-download feature, so download the items you need one at a time).
fess_basic_config.bulk- Configuration indices (19 indices covering crawl settings, scheduler, labels, key matches, roles, web/file authentication, and so on)fess_config.bulk- The same 19 indices plus runtime data such as crawling information, failure URLs, job logs, and the thumbnail queue (25 indices in total)fess_user.bulk- Users, roles, and groupssystem.properties- System settings, including general configurationfess.json- Index settings (shard count,index.knn, and so on)doc.json- Document mapping (field definitions)
Note
fess_config.bulkalready includes everything infess_basic_config.bulk. For a configuration backup before upgrading,fess_basic_config.bulk,fess_user.bulk, andsystem.propertiesare sufficient.Note
Log data such as search logs and click logs (
search_log.ndjson,click_log.ndjson,favorite_log.ndjson,user_info.ndjson) can also be downloaded from the same page. They are not needed if you only want to back up the configuration. Note that these*.ndjsonfiles cannot be restored by uploading them on the backup page (see “Rollback Procedure”).Configuration File Backup
TAR.GZ/ZIP version:
RPM version:
DEB version:
Note
/etc/sysconfig/fess(RPM version) and/etc/default/fess(DEB version) are environment variable files that set values such asFESS_PORT,FESS_HEAP_SIZE,SEARCH_ENGINE_HTTP_URL, andFESS_DICTIONARY_PATH. For the TAR.GZ/ZIP version, the equivalent settings are inbin/fess.in.sh.Customized Configuration Files
If you have customized configuration files, back up those as well:
Note
app/WEB-INF/classes/log4j2.xmlis the log configuration for the Fess main (web) process. Child processes such as the crawler use separate files (for example,app/WEB-INF/env/crawler/resources/log4j2.xml, one each forcrawler,suggest,thumbnail, andchunk— four in total), so back those up too if you have customized them.
Index Data Backup
Back up OpenSearch index data.
Method 1: Use Snapshot Feature (Recommended)
Back up the index using OpenSearch snapshot feature.
Note
To register a filesystem (fs) repository, you must first specify the backup destination directory in path.repo in OpenSearch’s opensearch.yml and restart OpenSearch.
Configure repository:
Create snapshot:
Verify snapshot:
Method 2: Backup Entire Directory
Stop OpenSearch and back up the data directory.
Docker Version Backup
OpenSearch data is stored in Docker volumes. compose-opensearch3.yaml defines two volumes: search01_data for index data and search01_dictionary for dictionary files.
Note
The actual volume names are prefixed with the Compose project name (by default, the name of the directory containing the Compose files). Check the exact names with:
Stop the containers, then back up the volumes. Specify the actual volume name, including the prefix, for -v in docker run:
Warning
If you specify -v with the unprefixed name search01_data, Docker does not reference the existing volume — it creates a new, empty volume with the same name instead. The command does not report an error, and an archive with empty contents is created, so it can look as though the backup succeeded.
Note
The Fess main container (fess01) has no dedicated volume of its own, so the two volumes above are the only backup targets. However, general settings changed from the admin UI and plugins installed from the admin UI are stored only inside the container and are lost when the container is recreated. Persist these instead by specifying them via FESS_JAVA_OPTS or FESS_PLUGINS in the Compose file.
Step 2: Stop Current Version
Stop Fess and OpenSearch.
The TAR.GZ/ZIP version does not include a stop script. If you started bin/fess with the -p option, stop it using the PID file:
If you started it without -p, find the process ID and kill it manually (-d alone does not create a PID file).
RPM/DEB version (systemd):
Docker version:
Step 3: Install New Version
The procedure varies depending on the installation method.
TAR.GZ/ZIP Version
Download and extract the new version:
Note
Fess archives are distributed only in ZIP format (
fess-15.8.0.tar.gzis not provided).Copy configuration from the old version:
If you have customizations, also copy the following:
Warning
Do not copy JSPs (
app/WEB-INF/view/) edited via “Design” in the admin UI as-is. If their structure differs from the JSPs in the new version, pages may not render correctly. Reapply your changes to the new version’s JSPs instead.If you are using the embedded OpenSearch (starting
bin/fesswithout settingSEARCH_ENGINE_HTTP_URL), also copy the index data:Verify configuration differences and adjust as necessary
RPM/DEB Version
Install the new version package:
Note
For the RPM version, the configuration files under /etc/fess/* are registered as %config(noreplace), so they are retained across upgrades (the new default files are placed alongside them with a .rpmnew suffix). If new configuration options have been added, manual adjustment may be necessary.
Warning
For the DEB version, /etc/fess/* is not registered as a conffile (the only conffiles are /etc/default/fess, /etc/init.d/fess, and /usr/lib/systemd/system/fess.service). As a result, running dpkg -i overwrites files such as /etc/fess/fess_config.properties with the new version’s files. Reapply the configuration you backed up in Step 1 after upgrading. Note that /etc/fess/system.properties is a runtime-generated file not included in the package, so it is not overwritten.
Docker Version
Obtain Compose files for the new version:
Pull new images:
Step 4: Upgrade OpenSearch
Fess 15.8 supports OpenSearch 3.8.0. If the OpenSearch you connect to is older than that, upgrade it using the following procedure.
Note
This procedure applies when you are managing OpenSearch manually on a TAR.GZ/ZIP or RPM/DEB installation. For the Docker version, pulling the new image in Step 3 updates OpenSearch and its plugins together, so this step is not required.
Important
Regardless of whether you use chunk-vector search (semantic search), Fess 15.8 always includes index.knn in the search index settings and content_chunk_vector (a knn_vector type) in the mapping. Because of this, the OpenSearch you connect to must have the k-NN plugin installed.
It is bundled with the standard OpenSearch distribution and the Docker version’s image.
It is not included in the minimal distribution, so creating a new index fails and |Fess| cannot start.
The index settings also always send
knn.derived_source.enabled. An older OpenSearch that does not recognize this setting fails to create the index regardless of whether the k-NN plugin is present.
See “Prerequisites” in Semantic Search (Content Chunking + Vector Search) for details.
Warning
Be careful when performing major version upgrades of OpenSearch. Index compatibility issues may occur. Fess 14.x uses the OpenSearch 2.x series, so upgrading from 14.x always falls into this case.
Install the new version of OpenSearch
Reinstall plugins:
Note
The version of these plugins must match the version of OpenSearch you use. Fess 15.8 supports OpenSearch 3.8.0. Installation fails if the versions do not match.
Start OpenSearch:
Step 5: Start New Version
TAR.GZ/ZIP version:
Note
Specifying -p creates a PID file, which lets you stop Fess the next time with kill $(cat /path/to/fess-15.8.0/fess.pid).
RPM/DEB version:
Docker version:
Step 6: Verify Operation
Check Logs
Verify there are no errors.
TAR.GZ/ZIP version:
RPM/DEB version:
Docker version:
Note
The same log directory also contains
fess-crawler.logfor crawl processing,audit.logfor authentication and admin operations, andsearchlog.logfor search requests.Access Web Interface
Access http://localhost:8080/ in a browser.
Log in to Admin Screen
Access http://localhost:8080/admin and log in with the administrator account.
Check the Version
In the admin UI, click “System Info” → “Config Info” and confirm that
fess.versionshown under “System Properties” reflects the new version.Verify Search Operation
Execute a search on the search screen and verify results are returned normally.
Step 7: Recreate Index (Recommended)
For major version upgrades, it is recommended to recreate the index.
Note
The steps below re-run the crawl; they do not update the index mapping (field definitions). If you need a re-index that updates the mapping — for example, to newly enable chunk-vector search (semantic search) — separately run “Re-indexing” under “System Info” → “Maintenance” in the admin UI. See Migrating from 15.7 or Earlier (in Semantic Search (Content Chunking + Vector Search)) for details.
Verify existing crawl schedules
Execute “Default Crawler” from “System” → “Scheduler”
Wait for crawl to complete
Verify search results
Warning
Re-indexing rebuilds the index with the new mapping, so it fails on an OpenSearch without the k-NN plugin. Review the notes in Step 4.
15.8-Specific Migration Tasks
If you are upgrading from 15.7 or earlier to 15.8, the following tasks may be required depending on which features you use.
If You Were Using Semantic Search
The fess-webapp-semantic-search plugin, which provided semantic search in 15.7 and earlier, is no longer needed (deprecated) because this functionality is now integrated into the core in 15.8. You need to remove the plugin, remove -Dfess.semantic_search.* and -Drank.fusion.searchers=default,semantic, and detach the old ingest pipeline. For the procedure, see Migrating from 15.7 or Earlier (in Semantic Search (Content Chunking + Vector Search)).
If You Were Using AI Search Mode (RAG)
Starting with 15.8, AI search mode (RAG) functionality has been split out into plugins such as fess-llm-ollama, fess-llm-openai, and fess-llm-gemini. Install the plugin that corresponds to the provider you use from “System” → “Plugins” in the admin UI.
If You Were Using SPNEGO (Windows Integrated Authentication)
Starting with 15.8, a SPNEGO login is rejected when the Kerberos realm of the client principal differs from the server realm. If your users log in from a child domain of an AD domain tree or from a trusted forest, list those realms in spnego.allowed.realms, separated by commas, from “System” → “General” in the admin UI or in app/WEB-INF/conf/system.properties. Otherwise users who could log in up to 15.7 are rejected with Kerberos realm is not allowed. For details, see SSO Configuration with Windows Integrated Auth.
The coded defaults of spnego.allow.unsecure.basic and spnego.allow.localhost also changed from true to false in 15.8. An installation where these keys are absent from app/WEB-INF/conf/system.properties inherits the stricter behavior on upgrade. In particular, with spnego.allow.unsecure.basic=false the SPNEGO library only offers Basic authentication for requests where HttpServletRequest#isSecure() returns true, so behind a reverse proxy that terminates TLS and forwards plain HTTP, clients that used to fall back to Basic authentication can no longer log in. Set tomcat.secure=true in tomcat_config.properties in that case; see SSO Configuration with Windows Integrated Auth for details.
Warning
A coded default only applies while the key is absent, and “System” → “General” in the admin UI writes every spnego.* key each time you save. An installation that ever pressed Update on that screen under 15.7 therefore still has spnego.allow.unsecure.basic=true and spnego.allow.localhost=true stored, so upgrading to 15.8 does not harden it: the permissive behavior is kept silently, and 15.8 only records a warning in fess.log when SPNEGO is initialized. Open “System” → “General” in the admin UI (or edit system.properties) and turn both off deliberately. spnego.allow.localhost=true is the more dangerous of the two, because the SPNEGO library then authenticates same-host requests as the server OS user with no Kerberos verification at all, which is unsafe behind a same-host reverse proxy.
If You Were Using SAML Authentication (SSO)
Starting with 15.8, Fess binds every SAML response to the ID of the AuthnRequest it sent, so IdP-initiated (unsolicited) SSO no longer works. A login started from a Fess tile in an IdP portal, such as the Okta dashboard or the Microsoft Entra ID “My Apps” portal, has no AuthnRequest to match against and is rejected. It worked up to 15.7 because Fess bounced the unmatched response back to the IdP and the IdP immediately returned a solicited assertion. If you place a tile on the IdP side, point it at the Fess /sso/ endpoint so that the login is SP-initiated.
The IdP also returns the assertion as a cross-site POST, so tomcat.sameSiteCookies in tomcat_config.properties must be set to none. With the shipped default lax the session cookie is not sent on that request and the SAML login cannot complete. This file is located in lib/classes/ for the ZIP package and in /etc/fess/ for the DEB/RPM packages, and Fess must be restarted after the change. Browsers only accept none on a cookie that also carries the Secure attribute, so Fess must be served over HTTPS. Up to 15.7 the same misconfiguration did not produce a clean error but an endless redirect loop back to the IdP, so check the setting even on a site that appeared to work; 15.8 fails once instead of looping. For details, see SAML Authentication SSO Setup.
If You Were Using Microsoft Entra ID (Azure AD)
Starting with 15.8, the response mode requested from the authorization endpoint defaults to query instead of form_post. Up to 15.7 the callback was returned as a cross-site POST, and the Fess default tomcat.sameSiteCookies = lax does not send the session cookie with such a request, so tomcat.sameSiteCookies = none was required. If you set none only for that reason, you can restore the default. To keep the previous behaviour, set entraid.response.mode=form_post and leave tomcat.sameSiteCookies = none in place. Browsers only accept none on a cookie that also carries the Secure attribute, so that path requires Fess to be served over HTTPS as well.
Starting with 15.8, Fess also resolves the user’s group and role membership in the background after login completes, instead of blocking the login on Microsoft Graph. Until resolution finishes — or if it does not fully succeed — the user holds only their own user-level permission and whatever entraid.default.groups and entraid.default.roles provide. With neither of those set, which is the shipped default, a search made in that window returns no documents at all, because a crawling configuration created with the shipped defaults grants {role}guest and a logged-in user does not hold that role. The search screen says so while resolution is in progress, and says something different if it did not fully succeed — the resolution counts as failed unless both the direct membership lookup and the nested group walk succeeded. Resolution is retried whenever the access token is renewed, and a later success clears the message, so a failure is not final for a session that outlives the token; to retry straight away, log out and log in again. For details, see SSO Configuration with Entra ID.
One consequence of resolving in the background: until it lands, the user’s resolved roles are not yet known. An administrator is therefore redirected to the search screen instead of the admin dashboard, and opening an administration page during that window returns them to the search screen. The window is up to about a second of scheduling delay plus the Microsoft Graph calls themselves — one for the direct memberships, then one more for each of those groups to walk the nested groups, issued one after another on a cold cache — so it grows with the number of groups the user belongs to. Access is only ever refused, never granted, in that window, and it needs no configuration to get past: authorization is evaluated again on every request of the same session, so once resolution has landed the administration screens open normally, without logging in again.
Warning
Do not shorten that window by putting the Fess administrator role in entraid.default.roles. That property is a single global value that Fess applies to every Entra ID user at login and re-applies on every later resolution, so it would give every user in the tenant permanent Fess administrator rights.
If You Use LDAP / Active Directory
From 15.8, the permission name of a group or role is the value of the entry’s RDN rather than a slice of the DN text. A group whose CN contains a character the DN escapes – a comma is the common one – therefore gets a different permission name than it did in 15.7.
| Group entry DN | Permission name up to 15.7 | Permission name in 15.8 |
|---|---|---|
CN=Sales\, EMEA,CN=Users,... | 2Sales | 2Sales, EMEA |
CN=Sales\, APAC,CN=Users,... | 2Sales | 2Sales, APAC |
Up to 15.7 several groups agreeing up to the comma collapsed onto one permission name, so members of Sales, EMEA and Sales, APAC could read each other’s documents and those of the Sales group. In 15.8 each gets its own permission name and that cross-group access does not happen.
In exchange, documents indexed under the old permission name are no longer visible to members of that group. If a crawling configuration’s permission setting holds an old permission name, update it to the new one and crawl (or reindex) again. If you use no group whose CN contains a comma or another escaped character, no permission name changes.
Change to ldap.role.search.user.enabled
Up to 15.7 the permission derived from the user name (role.search.user.prefix followed by the user name) was granted even with ldap.role.search.user.enabled=false. From 15.8 the setting takes effect and the permission is not granted when it is off.
In a deployment that sets it to false, users lose the permission named after themselves after the upgrade, so documents permissioned to an individual user stop matching for that user. To keep the previous behaviour, restore the shipped default of true.
Updating Plugin Versions
Plugins installed under app/WEB-INF/plugin/ need to be replaced with versions matching your Fess version. If you specify FESS_PLUGINS in the Docker version, update the version part, for example to fess-ds-wikipedia:15.8.0.
Rollback Procedure
If the upgrade fails, you can rollback with the following procedure.
Step 1: Stop New Version
Step 2: Restore Old Version
Restore configuration files and data from backup.
For RPM/DEB version:
Or:
Step 3: Restore Data
Restore from snapshot:
Or restore directory from backup:
For the Docker version, revert to the old version’s Compose files, then restore the volume contents:
Note
Configuration data downloaded from the admin screen can be re-imported after starting Fess via the upload feature on the “System Info” → “Backup” page. You can upload *.bulk files, *.properties files starting with system, *.xml files starting with gsa, *.json files starting with fess, and *.json files starting with doc — one file per operation. *.ndjson files such as search logs are not accepted and result in an error.
Warning
Uploading fess.json or doc.json overwrites the index definition files bundled with Fess itself. If you upload the fess.json or doc.json from an older version after upgrading, you lose the new version’s index settings and mapping. Do not upload these files except for rollback purposes.
Note
The uploaded system.properties is loaded into memory only and is not written back to a file, so its contents are lost when Fess is restarted. To restore it reliably, place the backed-up file directly in its proper location before starting Fess (app/WEB-INF/conf/ for the TAR.GZ/ZIP version, /etc/fess/ for the RPM/DEB version).
Note
The import runs asynchronously; the screen only shows that it has started. Check fess.log to confirm whether it actually succeeded.
Step 4: Start and Verify Service
Verify operation and confirm it has returned to normal.
Frequently Asked Questions
Q: Can I upgrade without downtime?
A: Upgrading Fess requires service shutdown. To minimize downtime, consider the following:
Verify procedures in a test environment first
Create backups in advance
Secure sufficient maintenance time
Q: Do I need to upgrade OpenSearch too?
A: Each version of Fess requires a specific version of OpenSearch. Fess 15.8 requires OpenSearch 3.8.0. The Fess OpenSearch plugins such as opensearch-analysis-fess must exactly match the OpenSearch version, so if you upgrade OpenSearch, also update the plugins to the corresponding version (3.8.0).
Also, Fess 15.8 requires the k-NN plugin and always sends knn.derived_source.enabled in the index settings. With an older OpenSearch, creating a new index fails, so upgrading OpenSearch is effectively required. See Step 4 for details.
Q: Do I need to recreate the index?
A: For a Fess minor version upgrade (15.x → 15.8) where you do not use chunk-vector search, it is usually not necessary. The existing index can continue to be used as-is, and settings such as content_chunker.enabled remain disabled by default, so behavior does not change.
Recreation and re-indexing are required in the following cases:
Newly enabling chunk-vector search (semantic search): The existing index does not pick up the new mapping, so re-indexing is required. See Migrating from 15.7 or Earlier (in Semantic Search (Content Chunking + Vector Search)) for details.
Upgrading from 14.x: Because OpenSearch undergoes a major version upgrade from 2.x to 3.x, recreating the index is recommended.
Warning
Operations that create a new index (including re-indexing) fail on an OpenSearch without the k-NN plugin. Review the notes in Step 4.
Q: Search results are not displayed after upgrade
A: Verify the following:
Verify OpenSearch is running
Verify indexes exist (
curl http://localhost:9200/_cat/indices)Re-run crawl
Next Steps
After the upgrade is complete:
Startup, Shutdown, and Initial Setup - Verify startup and initial configuration
Security Configuration - Review security configuration
Semantic Search (Content Chunking + Vector Search) - Chunk-vector search (semantic search) configuration and migration steps
Check release notes for new features