Log Configuration
There are two log files that you need to consider when troublshooting and debugging. Understanding both of these logs is crucial for the correct operation of your KMIP Server.
- The
kmip.server.logcovers the server topics like startup, HSM connection and database migration. - The
kmip.traffic.logrecords what individual KMIP clients sent and why a request was rejected. Warnings and errors from both are also mirrored tostderr, so the docker logs are often all you need.
The rest of this page covers where those files live, how to reach them in a running container, how to raise verbosity while diagnosing a problem, and how to forward logs to a SIEM. See the Log Reference page for more details on specific events and suggested actions.
Logging is configured in two files, both shipped in the delivery's config/ directory:
| File | Controls |
|---|---|
config/log4j2.xml | Log4j 2 configuration - appenders (log files, console, syslog), rotation policies, and per-logger levels. Edit this file to change log levels or enable syslog. |
config/kmipserver.properties | Application-level logging switches (debug on/off) and sensitive-data masking. |
Log4j 2 does not hot-reload - every logging change needs a server restart to take effect.
Log files
By default the KMIP Server depoyed with docker, it writes these files under /app/logs, which the
installer bind-mounts to ./data/kmip/logs on the host:
| File | Contents |
|---|---|
kmip.server.log | Main server log - the root logger writes here. |
kmip.traffic.log | KMIP protocol traffic - one line per operation, plus optional wire-format dumps (see Traffic logging). |
kmip.client.log | Output from the embedded interl KMIP client the server uses. Separated for development; can be folded into the server log in production. |
In addition, warnings and errors are mirrored to stderr, so they appear in docker logs / journalctl.
Reading the logs
# Live errors/warnings + operation lines (mirrored to stderr):
docker compose logs -f kmip-server
# Full log files, read straight from the host bind-mount:
tail -f data/kmip/logs/kmip.server.log
Rotation
The three log kmip.server.log, kmip.traffic.log, and kmip.client.log are rolling files.
Each rolls over daily or whenever it reaches 250 MB, whichever comes first.
Rolled files are gzip-compressed and named with the date and an index, for example:
kmip.server-2026-01-31-1.log.gz
Log4j 2's default rollover policy keeps rolled files indefinitely - there is
no automatic deletion. Manage retention with your own tooling or by adding a
DefaultRolloverStrategy max="…" if you need a bounded number of archives.
Loggers and levels
Per-component levels are defined as <Logger> elements in log4j2.xml.
The root level is info. The following loggers are configured:
| Logger | Default level | Purpose |
|---|---|---|
com.cryptsoft.kmipserver | info | Server core. |
com.cryptsoft.kmipserver.operations | info | One line per KMIP operation; mirrored to the console and the traffic log. |
com.cryptsoft.kmipserver.netty / io.netty | info | KMIP transport layer (Netty) - the listener on the TLS port. |
com.cryptsoft.kmipserver.PrimusShim | debug | HSM (Primus) connection layer - login and key-generation diagnostics. |
com.cryptsoft.kmipserver.PrimusCheck | debug | Periodic HSM Object Sync to the DB. |
com.cryptsoft.kmipserver.KmipConfig | debug | Startup configuration and database migration. |
com.cryptsoft.kmip | info | Embedded KMIP client (writes to kmip.client.log). |
The three HSM loggers are deployed with debug on purpose.
This way the information you most often need to diagnose HSM and migration problems is captured out of the box.
To change verbosity for a logger, edit its level
(one of trace, debug, info, warn, error, off) and restart the server.
For example:
<Logger name="io.netty" level="warn"/>
Traffic logging
The traffic log records the full KMIP request/response payloads in several wire formats.
Each format is a dedicated logger toggled with its level (info to enable, off to disable).
There are two parallel families:
- the first one is
com.cryptsoft.kmipserver.*, written tokmip.traffic.log - the second is the embedded client
com.cryptsoft.kmip.*, which has multiple logger suffixes
| Logger suffix | Format | Default level |
|---|---|---|
…hexlog | Raw TTLV hex dump | info (on) |
…xmllog | KMIP XML representation | info (on) |
…jsonlog | KMIP JSON representation | off |
…tagtextlog | Human-readable tag/value text | off |
By setting the level to info (on) or off you can manage which information flows from
the server logger com.cryptsoft.kmipserver.<suffix>,
or client logger com.cryptsoft.kmip.<suffix>.
Traffic logs can contain attribute values and other request data.
The hardened delivery ships with log.maskSensitive=true (see below) to redact sensitive fields.
We strongly recommend keeping this on, and restricting access to the ./data/kmip/logs directory accordingly.
Common tasks
HSM connectivity debugging
The HSM loggers should run at debug to show more details.
Enable it in the kmipserver.properties: primus.debug=true, restart the server and
watch kmip.server.log (or docker compose logs) at startup and during the periodic health check:
grep -E 'PrimusShim|PrimusCheck' data/kmip/logs/kmip.server.log
A failed login looks like this - see the Log Reference for the action:
WARN kmipserver.PrimusShim fetchHsmGeneration,
com.securosys.primus.jce.spi0.NotAuthorizedException: status: UserNotLoggedIn
Reducing log volume
The traffic hex and XML logs are the two largest contributors.
To keep one line per operation but drop the wire-format payloads, turn the dump loggers off in
log4j2.xml:
<Logger name="com.cryptsoft.kmipserver.hexlog" level="off"/>
<Logger name="com.cryptsoft.kmipserver.xmllog" level="off"/>
You can also adjust the verbose infrastructure logger (e.g. io.netty) to warn.
Forwarding logs to a SIEM (syslog)
The provided log4j2.xml and docker-compose.yml both include a commented-out syslog configuration.
To enable it, uncomment these three sections and set the target.
You do not need to author the appender yourself.
-
In
config/log4j2.xml, uncomment the<Syslog>appender inside<Appenders>:<Syslog name="syslog" format="RFC5424" host="${env:KMIP_SYSLOG_HOST}"port="${env:KMIP_SYSLOG_PORT:-6514}" protocol="${env:KMIP_SYSLOG_PROTOCOL:-SSL}"appName="kmip-server" newLine="true" ignoreExceptions="false"/> -
In the same file, uncomment the
<AppenderRef ref="syslog"/>on<Root>:<Root level="info"><AppenderRef ref="kmipserver"/><AppenderRef ref="consolewarn"/><AppenderRef ref="syslog"/></Root> -
In
docker-compose.yml, uncomment theenvironmentblock and set the collector address:environment:KMIP_SYSLOG_HOST: siem.example.internalKMIP_SYSLOG_PORT: "6514"KMIP_SYSLOG_PROTOCOL: SSL # SSL (TLS) | TCP | UDPVariable Default Description KMIP_SYSLOG_HOST(required) Hostname/IP of the syslog collector. KMIP_SYSLOG_PORT6514Destination port. KMIP_SYSLOG_PROTOCOLSSLTransport: SSL(TLS),TCP, orUDP. -
Restart the container:
docker compose up -d kmip-server.
Use SSL (TLS) transport in production so that log data containing operational detail, is encrypted in transit.