You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
bootstrap/setup.sh loads the optional LDIF files from /opt/opendj/bootstrap/schema/ and /opt/opendj/bootstrap/data/ with an unquoted password (setup.sh#L88, #L105):
A ROOT_PASSWORD that contains whitespace is split into several arguments, and one that contains *, ? or [ is subject to glob expansion. The bind then fails and the file is skipped. What that leads to depends on the image:
the released 5.1.2 image (reproduced below) reports itself healthy with the data missing, and the only trace is one line in the log;
on master, since Report the OpenDJ container healthy only once its bootstrap has succeeded #898, the exit status of setup.sh is that of its last command: a failed bind on the last data LDIF keeps the container from ever turning healthy, while a failed bind on a schema LDIF, or on an earlier data LDIF, is still skipped silently. The loads are meant to be tolerant (see the header of setup.sh); with --continueOnError, a refused entry leaves the exit status at 0, a failed bind does not.
Reproduced with openidentityplatform/opendj:latest (2026-07-17):
mkdir bdata
printf 'dn: ou=probe,dc=example,dc=com\nobjectClass: organizationalUnit\nou: probe\n' > bdata/10-probe.ldif
docker run -d --name sp -e ROOT_PASSWORD='two words' -e ADD_BASE_ENTRY=--addBaseEntry \
-v "$PWD/bdata:/opt/opendj/bootstrap/data:ro" openidentityplatform/opendj:latest
# after it is healthy:
docker logs sp | grep -A1 'Loading /opt/opendj/bootstrap/data'
# Loading /opt/opendj/bootstrap/data/10-probe.ldif ...
# The LDAP bind request failed: 49 (Invalid Credentials)
docker exec sp /opt/opendj/bin/ldapsearch -h localhost -p 1389 -D "cn=Directory Manager" -w 'two words' \
-b ou=probe,dc=example,dc=com -s base "(objectClass=*)" 1.1
# The LDAP search request failed: 32 (No Such Entry)
setup, dsconfig and import-ldif in the same script quote the password and are not affected.
Expected
Any password that setup accepts works for the LDIF loads too. The password is not passed on a command line at all: every tool used by the script has a file-based variant (setup --rootUserPasswordFile, dsconfig / import-ldif --bindPasswordFile, ldapmodify -j), which also keeps it out of /proc/<pid>/cmdline while the bootstrap runs. $file is quoted as well.
Also: pre-encoded passwords and ADMIN_PORT
Found while reproducing. The dsconfig set-password-policy-prop call that allows pre-encoded passwords before the data LDIFs are loaded names no host or port, so it goes to 4444 whatever ADMIN_PORT the server listens on. With a non-default ADMIN_PORT it fails (Unable to connect to the server at "localhost" on port 4444, not checked), and every entry of the data LDIFs that carries a pre-encoded password is refused (19 (Constraint Violation): Pre-encoded passwords are not allowed for the password attribute userPassword) while the container reports itself healthy. Checked with -e ADMIN_PORT=5444 on an image whose dsconfig call is as on master but whose password handling was already fixed, so that the binds themselves succeed.
Problem
bootstrap/setup.shloads the optional LDIF files from/opt/opendj/bootstrap/schema/and/opt/opendj/bootstrap/data/with an unquoted password (setup.sh#L88, #L105):A
ROOT_PASSWORDthat contains whitespace is split into several arguments, and one that contains*,?or[is subject to glob expansion. The bind then fails and the file is skipped. What that leads to depends on the image:5.1.2image (reproduced below) reports itself healthy with the data missing, and the only trace is one line in the log;master, since Report the OpenDJ container healthy only once its bootstrap has succeeded #898, the exit status ofsetup.shis that of its last command: a failed bind on the last data LDIF keeps the container from ever turning healthy, while a failed bind on a schema LDIF, or on an earlier data LDIF, is still skipped silently. The loads are meant to be tolerant (see the header ofsetup.sh); with--continueOnError, a refused entry leaves the exit status at0, a failed bind does not.Reproduced with
openidentityplatform/opendj:latest(2026-07-17):setup,dsconfigandimport-ldifin the same script quote the password and are not affected.Expected
Any password that
setupaccepts works for the LDIF loads too. The password is not passed on a command line at all: every tool used by the script has a file-based variant (setup --rootUserPasswordFile,dsconfig/import-ldif --bindPasswordFile,ldapmodify -j), which also keeps it out of/proc/<pid>/cmdlinewhile the bootstrap runs.$fileis quoted as well.Also: pre-encoded passwords and
ADMIN_PORTFound while reproducing. The
dsconfig set-password-policy-propcall that allows pre-encoded passwords before the data LDIFs are loaded names no host or port, so it goes to4444whateverADMIN_PORTthe server listens on. With a non-defaultADMIN_PORTit fails (Unable to connect to the server at "localhost" on port 4444, not checked), and every entry of the data LDIFs that carries a pre-encoded password is refused (19 (Constraint Violation):Pre-encoded passwords are not allowed for the password attribute userPassword) while the container reports itself healthy. Checked with-e ADMIN_PORT=5444on an image whosedsconfigcall is as onmasterbut whose password handling was already fixed, so that the binds themselves succeed.Notes
replicate.shis handled in Docker image: replicate.sh prints its environment, ROOT_PASSWORD included, to the container log #1084, which moves it to password files.