Skip to content

Master password overwritten on container recreation, causing keystore mismatch #789

@andreimirt

Description

@andreimirt

What is the bug or the crash?

When upgrading kartoza/geoserver by recreating the container (e.g., docker compose up -d after changing GS_VERSION), the master password stored in security/masterpw/default/passwd is overwritten with the default value from the image template, even though the data directory is persisted via bind mount. This causes GeoServer to fail to start with the error:

Caused by: java.security.UnrecoverableKeyException: Password verification failed
SEVERE: Context [/geoserver] startup failed due to previous errors

The keystore (geoserver.jceks) remains encrypted with the original master password, but the passwd file now contains a different value, causing a mismatch.

Steps to reproduce the issue

  1. Deploy kartoza/geoserver:2.26.1 with a persistent data directory (named volume or bind mount)
  2. Change the master password via GeoServer web UI (Security → Passwords → Change master password)
  3. Verify GeoServer works and note the encrypted password in data_dir/security/masterpw/default/passwd
  4. Recreate the container (e.g., upgrade by changing GS_VERSION and running docker compose up -d, or any other container recreation)
  5. GeoServer fails to start with "Password verification failed"
  6. Check data_dir/security/masterpw/default/passwd - it now contains a different encrypted string than before the recreation

Versions

kartoza/geoserver:2.26.1 (before upgrade)
kartoza/geoserver:2.28.0 (after upgrade)
Docker Compose v2

Additional context

The issue is in the startup scripts that copy the security template from the image. The image contains a baked-in default master password file at:

/usr/local/tomcat/security/masterpw/default/passwd

This file contains 3Gu9U3xKK1DdKLlI3KiqxXsFcetfUA54, which is the encrypted form of geoserver (the default master password). When the container is recreated, the startup scripts copy this template over the existing passwd file in the data directory, overwriting any custom master password that was set via the UI.

The overwritten value is deterministic (always 3Gu9U3xKK1DdKLlI3KiqxXsFcetfUA54), not random. This happens because the /settings/ directory (which contains .first_time_hash.lock) is ephemeral and gets reset on container recreation.

The workaround is to restore the encrypted passwd file from a backup after the upgrade:

cp ./data.backup/geoserver/security/masterpw/default/passwd ./data/geoserver/security/masterpw/default/passwd
docker compose restart geoserver

The passwd file is encrypted (see config.xml with true), so you cannot simply echo a plain-text password. You must restore the entire encrypted file from backup.

Possible fix: The startup scripts should check if geoserver.jceks already exists in the data directory before copying the security template. If the keystore exists, the passwd file should not be overwritten.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions