0 votes
by (120 points)
closed by

Hi there,

We've recently ran into an issue where using backslashes in the path causes SftpPathNotFoundException: Renci.SshNet.Common.SftpPathNotFoundException : Invalid path.

We have some unit tests set up where we spin up the FTP server locally and upload a file successfully with forward slashes. But once we change those to back slashes, the tests break with the above-mentioned exception.

I discovered the AcceptWindowsPaths setting, which I set to true. But nothing changed after setting this to true.

This is a small snippet of our setup:

var fileServer = new FileServer();
fileServer.Settings.AllowedAuthenticationMethods = AuthenticationMethods.Password;
fileServer.Settings.AcceptWindowsPaths = true;

fileServer.Authentication += this.Authenticate;
fileServer.PathAccessAuthorization += this.PathAccessAuthorization;

I would like to know if we did this right, or do we need more configuration? Also, is there an event that we can hook into so we can do the normalization ourselves?

Thank you & kind regards,

Thomas

closed with the note: Problem was not caused by Rebex.
Applies to: Rebex FTP/SSL

1 Answer

0 votes
by (150k points)

Normally, backslashes are not actually supposed to work with SFTP at all, and Rebex File Server's SFTP presents a file system that uses a forward slash ('/') character as a directory separator. This applies even when running on Windows, and it corresponds to SFTP protocol specification.

The AcceptWindowsPaths option is an exception to this, but it is still not supposed to switch the server's file system into 'backslash is a separator' mode. All it does is enable normalization of Windows-like paths on input (as a workaround for a specific instance of misbehaved SFTP client). This means that, for example, if the client sends the "d:\directory\file" path, the server treats it as "/d/directory/file". But if the SFTP client has additional expectations beyond this (for example, if it assumes that responses to SSH_FXP_REALPATH command use paths with backslashes as well), interoperability issues are very likely. But to be able to tell what exactly went wrong, we would have to know which path format was actually used in the request that failed with "Invalid path" error.

by (120 points)
Hi Lukas, thanks for your swift reply.

The client who is trying to connect to our server is hosted on a Windows machine. They told us their SFTP client is converting it into a Windows path, something similar to: sftp://sftp.domain.io/path\OUT. (I anonymized our domain).

If possible, we would like to receive this path and normalize it on the server side. However, it seems that Rebex already throws this exception somewhere internally.


Thanks again,

Thomas
by (150k points)
Hi Thomas, can you enable [ogging at LogLevel.Verbose (https://www.rebex.net/file-server/features/logging.aspx) at the server, and see which "Resolving path" entries are there in the log when the client receives the "invalid path" error?
by (120 points)
Hi Lucas, I enabled LogLevel.Verbose and ran the test (locally) once. This is the output. I don't see any Resolving path entries. I removed our company name and replaced it with Test. Just so you know.


2025-12-09 16:05:31.513 Opening log file.
2025-12-09 16:05:31.514 INFO FileLogWriter(1)[42] Info: Assembly: Rebex.Common 7.0.9313 for .NET 9
2025-12-09 16:05:31.514 INFO FileLogWriter(1)[42] Info: Platform: Windows 11 (Build 22631) 64-bit; CLR: .NET 10.0.0
2025-12-09 16:05:31.514 DEBUG FileLogWriter(1)[42] Info: Culture: en; windows-1252
2025-12-09 16:05:31.533 INFO FileSystemProvider(589813455)[42] ---Vfs;TestFileSystemProvider_1_1;---: BEGIN - VfsDelegateProvider - Exists
nodePath - TestFileSystemProvider_1_1:/

2025-12-09 16:05:31.540 INFO FileSystemProvider(589813455)[42] ---Vfs;TestFileSystemProvider_1_1;---: BEGIN - VfsDelegateProvider - NodeToPath
node - TestFileSystemProvider_1_1:/

2025-12-09 16:05:31.541 INFO FileSystemProvider(589813455)[42] ---Vfs;TestFileSystemProvider_1_1;---: END - VfsDelegateProvider - NodeToPath
node - TestFileSystemProvider_1_1:/
Return Value - TestFileSystemProvider_1_1:/

2025-12-09 16:05:31.542 INFO FileSystemProvider(589813455)[42] ---Vfs;TestFileSystemProvider_1_1;---: END - VfsDelegateProvider - Exists
nodePath - TestFileSystemProvider_1_1:/
Return Value - True

2025-12-09 16:05:31.546 INFO FileSystemProvider(589813455)[42] ---Vfs;TestFileSystemProvider_1_1;---: BEGIN - VfsDelegateProvider - GetRootDirectory

2025-12-09 16:05:31.547 INFO FileSystemProvider(589813455)[42] ---Vfs;TestFileSystemProvider_1_1;---: END - VfsDelegateProvider - GetRootDirectory
Return Value - TestFileSystemProvider_1_1:/

2025-12-09 16:05:31.557 INFO FileSystemProvider(589813455)[41] ---Vfs;TestFileSystemProvider_1_1;---: BEGIN - VfsDelegateProvider - GetNode
nodePath - TestFileSystemProvider_1_1:/

2025-12-09 16:05:31.558 INFO FileSystemProvider(589813455)[41] ---Vfs;TestFileSystemProvider_1_1;---: END - VfsDelegateProvider - GetNode
nodePath - TestFileSystemProvider_1_1:/
Return Value - TestFileSystemProvider_1_1:/

2025-12-09 16:05:31.558 INFO FileSystemProvider(589813455)[41] ---Vfs;TestFileSystemProvider_1_1;---: BEGIN - VfsDelegateProvider - GetNodeLength
node - TestFileSystemProvider_1_1:/

2025-12-09 16:05:31.560 INFO FileSystemProvider(589813455)[41] ---Vfs;TestFileSystemProvider_1_1;---: END - VfsDelegateProvider - GetNodeLength
node - TestFileSystemProvider_1_1:/
Return Value - 0
by (150k points)
This looks like you only set LogWriter property in FileSystemProviderSettings instead of the one on FileServer class:
https://www.rebex.net/doc/api/Rebex.Net.Servers.FileServer.LogWriter.html
https://www.rebex.net/doc/api/Rebex.IO.FileSystem.FileSystemProviderSettings.LogWriter.html

Would it be possible to set up a log writer on FileServer object as well?
var fileServer = new FileServer();
fileServer.LogWriter = new FileLogWriter(...);
by (120 points)
Hi Lukas,

I think we found the problem. First of all, there is no issue with the Rebex FileServer implementation.


Our consumer is using the SSH.NET SFTP NuGet package. This package inserts a forward slash when it does not detect a forward slash at the first character of the string. Resulting in '/\xxx'.

Thanks for your time and assistance.

With kind regards,
Thomas
...