Troubleshooting

This chapter covers common problems you may encounter when running Stylus SFTP Server and provides step-by-step guidance for diagnosing and resolving each issue.

Server Won't Start

Symptom Cause Resolution
Server exits immediately with no output Error details are written to the log file, not the console. Check logs/stylus-sftp.log for the root-cause error message.
LICENSE_REJECTED in log Activation key is missing, expired, or tampered. Place a valid activation.key file in the data directory root. Verify the key has not expired.
Address already in use Another process is listening on port 22 (or the configured SFTP port). Change the port in sftp-server.xml, or stop the conflicting service. On Windows, run netstat -ano | findstr :22 to identify the process.
Database may be already in use An H2 lock file remains from a previous crash. Delete db/sftpdb.lock.db in the data directory and restart the server.
UnsupportedClassVersionError or JAVA_HOME not found Java 21 or later is not installed, or the bundled JRE is missing. Ensure Java 21+ is installed and JAVA_HOME points to it, or verify the bundled JRE directory exists under the installation root.

Authentication Failures

Symptom Cause Resolution
XML provider: password always rejected Password hash in users.xml is malformed. Verify the hash is in BCrypt format ($2a$12$...). Use admin hash-password to generate a valid hash.
JDBC provider: all logins fail Database is unreachable or credentials are wrong. Run admin test-connection to verify database connectivity. Check the JDBC URL, username, and password in sftp-server.xml.
LDAP: authentication times out or fails Service account credentials, base-dn, or username-attribute are incorrect. Verify the <ldap> block in sftp-server.xml: service account DN and password, <base-dn>, and <username-attribute> (typically sAMAccountName for Active Directory).
Account locked Too many consecutive failed login attempts triggered the lockout threshold. Check the sftp_lockout table or run admin unlock-user <username> to clear the lockout.
Public key: Auth fail despite correct key Key file is in PuTTY .ppk format instead of OpenSSH format. Convert the key to OpenSSH format using PuTTYgen (Conversions → Export OpenSSH key) and update keys.xml.

Upload Issues

Symptom Cause Resolution
Uploaded file is 0 bytes Disk quota exceeded — the server discards partial uploads when the hard limit is reached. Check the user's quota with admin get-quota <username>. Increase the quota or free up space in the user's home directory.
UPLOAD_REJECTED in audit log User has read-only access, quota hard limit was hit, or a path traversal attempt was blocked. Verify the user's access level in the authentication provider. Check quota limits. Review the audit detail field for the specific rejection reason.
Staging .tmp files not renamed to final name The staging directory and target directory are on different filesystem volumes. ATOMIC_MOVE requires source and target to be on the same volume. Ensure <home-root> in filesystem-config.xml does not span mount points or drive letters.
Orphan .tmp files accumulating Clients disconnected during upload; cleanup runs on server startup. Restart the server to trigger orphan cleanup, or wait for the configured orphan-max-age to expire. Orphan files older than the threshold are automatically removed.

Connection Issues

Symptom Cause Resolution
Connection refused for specific IPs IP address is in the block list. Review <block-list> entries in sftp-server.xml. Remove the offending CIDR block if the IP should be allowed.
Connection refused after many rapid attempts Source IP exceeded the max-connections rate limit and was temporarily blacklisted. Wait for blacklist-duration to expire (default is a few minutes). Reduce connection frequency from the client, or increase the rate limit in sftp-server.xml.
Connection dropped with no error GeoIP blocking rejected the client's country. Verify the client's country is in the GeoIP allow list (or not in the deny list). Use admin geoip-lookup <ip> to check the resolved country.
External clients cannot connect Firewall is blocking the required ports. Ensure the SFTP port (default 22) is open. For FTPS, also open the passive port range (default 50000–50100). Check both host firewall and network firewall rules.
Client refuses to connect after a reinstall or upgrade, reporting REMOTE HOST IDENTIFICATION HAS CHANGED (OpenSSH) or a host-key mismatch prompt (WinSCP / FileZilla) The server's host-key files (hostkey-*.ser) were lost or regenerated, so the server now presents a different key than the client has pinned in its known_hosts. Common causes: the data directory was wiped and recreated, the files were deleted, or an older build stored them under the read-only install directory where the LocalService account could not preserve them. If the change was not intentional, restore the original hostkey-*.ser files from a backup of ${STYLUS_SFTPSERVER_DATA}\conf\ so the server presents its original identity again. If the change was intentional (e.g., you deliberately rotated keys), remove the stale entry from each client's known_hosts (OpenSSH: ssh-keygen -R <host>) or accept the new key at the client's prompt. To prevent recurrence, confirm the host-key paths in sftp-server.xml point under ${STYLUS_SFTPSERVER_DATA} (the writable data directory), not the install directory, and include conf\hostkey-*.ser in your backup routine.

FTPS Issues

Symptom Cause Resolution
keystore not found or alias not found The keystore path or key alias in the FTPS configuration is incorrect. Verify <keystore-path> and <keystore-password> in the FTPS section. Use admin list-certs to inspect the keystore contents.
TLS handshake failure Client and server do not agree on a TLS protocol version. Ensure both sides support the same TLS version. The server defaults to TLSv1.2 and TLSv1.3. Check <ssl-protocols> in the FTPS configuration.
Connection timeout on FTPS port Client is using implicit mode but server is configured for explicit (or vice versa). Implicit TLS expects TLS negotiation immediately on connect; explicit TLS starts plain and upgrades via AUTH TLS. Ensure the client mode matches the server's <implicit> setting.
Data channel fails after successful login Passive port range is not open in the firewall. Open the passive port range (configured in the FTPS section, default 50000–50100) in both the host firewall and any network firewalls.

Web Console / Portal

Symptom Cause Resolution
Cannot access the web admin console Bind address restricts access, or the port is wrong. Check <bind-address> and <port> in admin-console.xml. A bind address of 127.0.0.1 means only localhost connections are accepted. Change to 0.0.0.0 for remote access.
File Transfer Portal returns 404 or is inaccessible The portal is disabled by default. Set <enabled>true</enabled> in the <file-portal> section of admin-console.xml and restart Tomcat.
Portal login fails but SFTP login works (or vice versa) The portal and admin console use different credential stores. The portal authenticates with SFTP user credentials (same as the SFTP authentication provider). The admin console uses a dedicated admin account. Verify you are using the correct credentials for each interface.
Admin or portal session expires while the user is actively working Session cookies are cleared, or the session inactivity timeout was reached (30 min default). Check <session-timeout-minutes> in admin-console.xml (both for the admin console and for the file-portal block). Extend if legitimate work sessions run long. Note that the session timer resets on server-round-trip activity; long idle periods on the client side (typing without saving) still expire.
SFTP user cannot cd into a virtual folder they should have access to The mount table for the user has a conflict (two different real paths mapped to the same logical path), or the physical directory is missing or unreadable. Run admin mount-conflicts <username> to see conflicts (with the groups that introduce them). Run admin folder-health to spot MISSING folders. Also check the server log: when a folder cannot be mounted at session start, the server logs an explicit WARN naming the folder and the exact reason — e.g. Virtual folder '…' (folder_id=…) real path does not exist, … is not a directory, or … is not readable by the server account. Fix the group memberships or restore the underlying directory, then have the user reconnect.
A virtual folder shows up as MISSING for every user, or a folder silently never appears for anyone The physical directory backing the folder does not exist on disk, or the SSS process lacks read access to it. Reconciler status updates every 30 min by default. Verify the path in the Virtual Folders admin tab matches an existing directory. Grep the server log for Virtual folder WARN lines to see the precise cause. Because the Windows service runs as LocalService, that account must have read access to the target directory (and Full Control for read-write folders) — a path under another user's profile or a share the service cannot reach is the usual cause. Grant the ACL, or edit the folder's real path to point at a location the service account can read.

Email Notifications

Symptom Cause Resolution
Notifications are not being sent Email notifications depend on the JDBC audit sink for event data. Ensure the JDBC audit sink is enabled in sftp-server.xml. Without it, the notification engine has no events to process.
SMTP connection errors in the log SMTP server is unreachable or credentials are wrong. Run admin test-email --to you@example.com to diagnose SMTP connectivity. Verify host, port, TLS settings, and credentials in the SMTP configuration.
Gmail rejects authentication Gmail requires App Passwords for non-OAuth access. Generate an App Password in your Google Account security settings and use it instead of your regular Gmail password. Regular passwords are rejected when 2-Step Verification is enabled.

Performance

Symptom Cause Resolution
High memory usage or OutOfMemoryError Default JVM heap is too small for the workload. Increase the heap size with JVM options (e.g., -Xmx2g) in the service wrapper configuration or start script.
Slow directory listings Home directory contains a very large number of files. Organize files into subdirectories. Consider archiving or removing old files periodically.
Audit events dropped or queue full warning The async audit queue is saturated under heavy load. Increase <queue-capacity> in the JDBC audit configuration (default is 10,000). Also verify that the database is not a bottleneck.

Database

Symptom Cause Resolution
H2 database corruption or file corrupted error Database files were damaged by an unclean shutdown. Stop all JVMs accessing the database, delete any .lock.db files, and restart. In severe cases, restore from a backup.
Migrating from H2 to MySQL or PostgreSQL Planned upgrade to an external database. Export existing data from H2, update the driver class, JDBC URL, username, and password in all configuration files (sftp-server.xml, admin-console.xml), then restart. Use admin init-db to create the schema on the new database.
Tables missing after fresh install Schema was not auto-created (e.g., insufficient database permissions). Run admin init-db to create all required tables. Verify the database user has CREATE TABLE privileges.

Log Files

The server writes diagnostic information to several log destinations. When reporting issues, always include the relevant log output.

Log Location Purpose
Main server log logs/stylus-sftp.log All server activity: startup, shutdown, errors, warnings, and informational messages.
Audit log (optional) Configured via Log4j 2 appender Dedicated file for audit events. Add a RollingFileAppender for the com.ivitechnologies.stylussftpserver.audit logger in log4j2.xml.
Log4j 2 configuration logs/log4j2.xml Controls log levels, appenders, and rotation. Edit to increase verbosity for debugging (set root level to DEBUG or TRACE).
Tip For transient issues that are hard to reproduce, temporarily set the log level to DEBUG in log4j2.xml. Remember to revert to INFO after capturing the needed output, as DEBUG generates significantly more log data.