Skip to main content
This page covers the most frequently encountered issues with phoss SMP and their solutions.

Startup issues

Symptoms: Exception at startup mentioning keystore, certificate, or PKCS12.Causes and fixes:
  • File not found: The path in smp.keystore.path is wrong or not readable by the process user. Use an absolute path in production.
  • Wrong password: smp.keystore.password and smp.keystore.key.password must both be correct and must match each other.
  • Wrong alias: smp.keystore.key.alias must exactly match the alias in the keystore. Check with:
    keytool -list -v -keystore smp.p12 -storetype PKCS12 -storepass yourpassword
    
  • Multiple entries: phoss SMP requires exactly one key entry in the keystore. Remove any extra entries.
  • Type mismatch: Set smp.keystore.type to match the actual file format: jks, pkcs12, or bcfks.
Symptoms: IllegalStateException: No SMP backend registered with ID 'xyz' or similar.The value of smp.backend does not match any registered backend ID. Valid built-in values are xml, sql, and mongodb. Verify the spelling in application.properties.If you are using a custom backend, ensure the backend JAR is on the classpath and the META-INF/services/ file contains the correct class name.
Symptoms: Warnings or errors about unreadable or unwritable directories.Set webapp.datapath to an absolute path and ensure the process user has read/write access:
webapp.datapath = /var/smp
sudo chown -R tomcat:tomcat /var/smp
sudo chmod 750 /var/smp

REST API issues

Symptoms: GET or PUT to /iso6523-actorid-upis%3A%3A0088%3A5060000000001 returns HTTP 400 or 404.Peppol and BDXR participant identifiers may contain encoded slashes (%2F) in some schemes. Tomcat rejects these by default.Fix for Tomcat 10+: Add encodedSolidusHandling="decode" to the <Connector> in server.xml:
<Connector port="8080" protocol="HTTP/1.1"
           encodedSolidusHandling="decode"
           ... />
Fix for Tomcat < 10: Set the JVM system property:
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
Symptoms: REST API calls return HTTP 401 even with correct credentials.
  • Bearer token (preferred): Create a token in the management UI under Administration > Security > User Tokens. Use it as:
    curl -H 'Authorization: Bearer <token>' https://smp.example.org/...
    
  • Basic auth: Credentials are email:password Base64-encoded. Verify the email address (not just a username) and that the password has not been changed since the credential was created.
  • Wrong encoding: Basic auth requires Base64(email:password). Some tools incorrectly encode username:password without the domain.
The user account performing writes must have the SMP administrator role. In the management UI, go to Administration > Security > Users and confirm the user has the correct role assigned.
Verify that smp.identifiertype and smp.rest.type are consistent:
smp.identifiertypesmp.rest.type
peppol or peppol-laxpeppol
bdxr1bdxr
bdxr2bdxr
Mixing these values produces responses with incorrect XML namespaces.

SML registration issues

The SML validates that the SMP certificate was issued by the Peppol PKI. Ensure:
  • You are using the correct certificate for the environment (test vs production)
  • The certificate has not expired (keytool -list -v shows the validity period)
  • smp.truststore.path points to the truststore matching the environment
phoss SMP needs outbound HTTPS access to the SML endpoint. Check firewall rules and test manually:
# Test environment
curl -v https://acc.edelivery.tech.ec.europa.eu

# Production environment
curl -v https://edelivery.tech.ec.europa.eu
If you use an HTTP proxy, configure it:
https.proxyHost = 10.0.0.10
https.proxyPort = 8080
DNS propagation can take a few minutes. If the record does not appear after 10 minutes:
  • Verify sml.smpid exactly matches the SMP ID registered with your Peppol Authority
  • Check the phoss SMP log for any warning during the SML call
  • Query the SML DNS zone directly to bypass local cache:
    nslookup SMP-MYID.publisher.acc.edelivery.tech.ec.europa.eu 8.8.8.8
    

Docker issues

Symptoms: The container starts but fails to write data files; errors mention /var/smp or similar paths.The Tomcat process inside the container typically runs as a non-root user. Mount a named volume and ensure the host directory is writable:
docker run \
  -v /host/smp-data:/var/smp \
  -e JAVA_OPTS="-Dconfig.file=/var/smp/application.properties" \
  phelger/phoss-smp-xml:latest
Set the owner of the host directory to the UID used inside the container (often UID 1000 or the Tomcat user):
sudo chown -R 1000:1000 /host/smp-data
Check the Docker logs for the first error:
docker logs <container-id> 2>&1 | head -100
Common causes: missing or unreadable keystore file, wrong application.properties path, or missing environment variable.

Database issues (SQL backend)

Verify the JDBC connection settings in application.properties:
jdbc.driver   = com.mysql.cj.jdbc.Driver
jdbc.url      = jdbc:mysql://localhost:3306/smp?useSSL=false&allowPublicKeyRetrieval=true
jdbc.user     = smp
jdbc.password = smp
target-database = MySQL
Test the connection independently:
mysql -h localhost -u smp -psmp smp -e "SELECT 1"
Supported values for target-database: MySQL, PostgreSQL, Oracle, DB2.
phoss SMP uses Flyway for schema migrations. If a migration fails:
  • Check the Flyway error in the log — it includes the migration script name and the SQL error
  • Ensure the database user has DDL privileges (CREATE TABLE, ALTER TABLE, etc.)
  • If you are upgrading from an older version, consult the Migrations guide
Tune the DBCP2 connection pool (available from v8.0.11):
jdbc.pooling.max-connections              = 20
jdbc.pooling.max-wait.millis             = 10000
jdbc.pooling.between-evictions-runs.millis = 300000
jdbc.pooling.min-evictable-idle.millis   = 1800000
Increase max-connections if the server is under sustained load. Restart is required after changing pool settings.

MongoDB issues

Verify the MongoDB connection URI in application.properties and that the MongoDB instance is reachable:
mongosh "mongodb://localhost:27017/smp" --eval "db.runCommand({ ping: 1 })"
If authentication is required, include credentials in the URI:
mongodb.uri = mongodb://smpuser:smppass@localhost:27017/smp?authSource=admin
phoss SMP creates collections on first write. If collections are missing, the backend may not have been initialised. Check the startup log for backend initialisation messages and ensure smp.backend = mongodb.

Reverse proxy issues

If phoss SMP is deployed under a context path (e.g. /smp) but accessed via a proxy at the root, all internal links will be broken.Set smp.forceroot = true to strip the context path from all generated links:
smp.forceroot  = true
smp.publicurl  = https://smp.example.org
SMP responses include the server’s own URL. If these are wrong, consuming clients cannot follow links.Set smp.publicurl to the exact public URL and choose the correct mode for how the proxy forwards host information:
smp.publicurl      = https://smp.example.org
smp.publicurl.mode = x-forwarded-header   # if proxy sets X-Forwarded-Host
# or
smp.publicurl.mode = forwarded-header     # if proxy sets RFC 7239 Forwarded
# or
smp.publicurl.mode = request              # use the incoming request URL directly

UI issues

Symptoms: The management UI loads but some elements are broken; browser DevTools console shows CSP errors.CSP is enabled by default (csp.enabled = true). To diagnose without disabling CSP entirely, enable reporting-only mode temporarily:
csp.enabled        = true
csp.reporting.only = true
This logs violations without blocking anything. Once you identify the blocked resource, adjust the CSP policy or, if the resource is from a trusted source, whitelist it.To disable CSP entirely (not recommended for production):
csp.enabled = false
By default (webapp.security.login.errordetails = true), failed login attempts show whether the username or password was wrong. In production, set this to false to avoid leaking account existence information:
webapp.security.login.errordetails = false
Listing all registered participants on the public start page can expose sensitive information. Disable it:
webapp.startpage.participants.none = true

Log analysis

phoss SMP uses Log4j 2 with SLF4J. Log output goes to the application server’s standard output by default. Enable debug logging for SMP components:
<!-- log4j2.xml -->
<Logger name="com.helger.phoss.smp" level="DEBUG" additivity="false">
  <AppenderRef ref="Console"/>
</Logger>
Key log patterns to look for:
PatternMeaning
Keystore loading failedKeystore path, password, or alias problem
No SMP backend registeredsmp.backend value does not match any backend ID
SML registrationSML call result (success or error detail)
SMPRestFilterIncoming REST request dispatch
DAOExceptionXML backend file read/write failure
FlywaySQL migration status
Set global.debug = true temporarily to get verbose request logging. Always set it back to false before going to production.

Build docs developers (and LLMs) love