dotnet / SqlClient

Microsoft.Data.SqlClient provides database connectivity to SQL Server for .NET applications.
MIT License
851 stars 285 forks source link

"System.Data.SqlClient is not supported on this platform" on .NET 6 on RHEL and AlmaLinux, works fine on .NET 5 and under Ubuntu #1643

Closed alex-jitbit closed 2 years ago

alex-jitbit commented 2 years ago

Describe the bug

We have a cross platform ASP.NET 6.0 app (published as "portable") that runs fine on Windows, Ubuntu etc, but throws the above error on RHEL and AlmaLinux. Reverting to the older version of the app that targets .NET 5 works fine.

Both versions System.Data.SqlClient 4.8.3 and Microsoft.Data.SqlClient throw this error. My connection-string uses an SQL user with a password, not using Kerberos or windows-integrated authentication.

System.PlatformNotSupportedException: Microsoft.Data.SqlClient is not supported on this platform.
at Microsoft.Data.SqlClient.SqlConnection..ctor(String connectionString)

To reproduce

Create a .NET Core 6.0 app that references SqlClient, publish, deploy to RHEL, run with dotnet MyProject.dll

THIS IS TRIVIALLY REPRODUCABLE on AlmaLinux 8 under WSL2 (available in MS Store). But it works fine under Ubuntu under WSL2.

Install WSL2, install Almalinux 8 from MS Store, run sudo yum install dotnet-sdk-6.0 -y to install dotnet, then run the app using dotnet MyProject.dll

Almalinux dotnet--info output:


.NET SDK (reflecting any global.json):
 Version:   6.0.105
 Commit:    679e7e16e1

Runtime Environment:
 OS Name:     almalinux
 OS Version:  8.5
 OS Platform: Linux
 RID:         rhel.8-x64
 Base Path:   /usr/lib64/dotnet/sdk/6.0.105/

Host (useful for support):
  Version: 6.0.5
  Commit:  70ae3df4a6

.NET SDKs installed:
  6.0.105 [/usr/lib64/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.5 [/usr/lib64/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.5 [/usr/lib64/dotnet/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download```
JRahnama commented 2 years ago

@alex-jitbit this seems like duplication of #1390 and some other similar issues when using Kerberos authentication on Unix. Please check that issue thread.

alex-jitbit commented 2 years ago

@JRahnama nope, not using Kerberos auth, simply MS SQL user with password. This is a library/targeting/dependency issue, strictly

ErikEJ commented 2 years ago

What is your Publish command?

alex-jitbit commented 2 years ago

@ErikEJ it's dotnet publish ..\path\to\MyProject.csproj --configuration Release -o path\to\OutputFolder

Once again, the same build works fine on Ubuntu, Windows Server etc. But some linux distros throw this error.

Wraith2 commented 2 years ago

The System version of the library can only be updated as part of the runtime. The last runtime it shipped with was netcore 3.1. So regardless of the bug status I don't think it's going to get fixed in the System version.

Can you try with the Microsoft version of the library from this repo and see if it reproduces?

JRahnama commented 2 years ago

@alex-jitbit I will look into this, but as a wild guess could this be related/similar to #1249 and #81?

alex-jitbit commented 2 years ago

@JRahnama nope, I'm not using docker, it's a standalone SQL Server installation, accessed over network. And a standalone aspnetcore app (also - not in docker)

alex-jitbit commented 2 years ago

@Wraith2 just tried with Microsoft.Data.SqlClient

! SAME ERROR !
System.PlatformNotSupportedException: Microsoft.Data.SqlClient is not supported on this platform.
: at Microsoft.Data.SqlClient.SqlConnection..ctor(String connectionString)
alex-jitbit commented 2 years ago

The exception is trivially reproducible on WSL2: just install AlmaLinux 8 from MS Store and run any NET6 app. SqlConnection constructor throws this error.

NET5 works fine. NET6 also works fine, but only on Ubuntu, not RHEL or its forks

ErikEJ commented 2 years ago

Have you tried using the latest SDK?

alex-jitbit commented 2 years ago

@ErikEJ no, but I have tried installing dotnet as described in MS docs

Have you tried the steps to repro I provided?

AraHaan commented 2 years ago

I would try it with the latest .NET 6 servicing release first.

ErikEJ commented 2 years ago

Yes 6.0.105 is not the latest SDK

alex-jitbit commented 2 years ago

@ErikEJ @AraHaan just updated to 6.06 and 6.0.106 - same exact error

UPD: sorry, just realized 106 is not the latest, will update and get back. Once I figure out how to update from MS package sources...

ErikEJ commented 2 years ago

Latest is 6.0.301 I think - but it can be confusing

alex-jitbit commented 2 years ago

I have just installed the latest aspnetcore 6.0.6 runtime, which is the latest servicing release, and have the same exact error.

It really feels like you guys are just dragging the issue. Meanwhile almost a dozen of our customers are waiting for a fix.

P.S. do I really need the SDK installed to run apps though? Isn't the runtime enough? I spent an hour trying to find a way to install the "latest SDK" on RHEL/Alma/etc, and MS website does not describe any info. If you really want me to - please provide the instructions. https://docs.microsoft.com/en-us/dotnet/core/install/linux-rhel - is not very helpful.

Wraith2 commented 2 years ago

I'm building a WM with nested virtualization enabled so I can setup all the stuff needed for wsl2 debugging. If it was a simple fix I wouldn't need to do that. So yes I imagine you're right that we're all dragging this out but it's because it's not a trivial thing to setup debugging for.

alex-jitbit commented 2 years ago

@Wraith2 appreciate

Wraith2 commented 2 years ago

The source of the problem in the current code is AliasRegistryLookup which is called from TdsParserStaticMethods.AliasRegistryLookup(ref host, ref protocol); it uses the registry which throws a type initialization exception because it isn't supported on non-windows.

https://github.com/dotnet/SqlClient/blob/d8fcedebc2c0112eaec43bd35feab5530fd9f1d0/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserStaticMethods.cs#L24-L31

notice the comment and lack of try block.

Wraith2 commented 2 years ago

Overall the lib is behaving as if it's running on windows, which is odd. have you tried a more mainstream liux?

AraHaan commented 2 years ago

Looks to me like it should be using the newer OperatingSystem class to guard against the call to the registry (which does not exist in linux unless running on wine).

I am surprised it does not throw on all unix OS’s.

Wraith2 commented 2 years ago

If I guard that error I hit an error in SNIInitialize when it can't load the sni.dll file. That means that it's trying to use the windows implementation. The nuget restore shouldn't be be choosing that implementation. So it isn't that we're doing anything wrong in code at runtime only that the wrong implementation was chosen. I don't know exactly where that choice is made, or how. Cross platform isn't an area that I'm well versed in.

AraHaan commented 2 years ago

perhaps the issue is that they are not publishing it as FDD dependent but as rid specific as well (by using --self-contained false).

Also I think having them skip the apphost as well to force usage of dotnet here would be the way to go.

Wraith2 commented 2 years ago

There's no deployment step at all. Both through wsl debugging and directly using dotnet run it uses the windows assembly. It shouldn't.

AraHaan commented 2 years ago

That is odd.

alex-jitbit commented 2 years ago

Any news regarding this issue? SqlClient is currently unusable on Linux.

Wraith2 commented 2 years ago

It is usable under some Linux, just not the specific one that you want to use. We need to know why the nuget restore process isn't identifying your distro as Linux and that isn't something that is part of this library. You may need to open an issue on nuget and get their help.

alex-jitbit commented 2 years ago

@Wraith2 wow, OK thanks. Please let me know where should I transfer the issue for you.

DavoudEshtehari commented 2 years ago

Would be related to #1631.

MarkpageBxl commented 2 years ago

When publishing a project depending on System.Data.SqlClient on Linux with .NET 6.0.108, we seem to end up with the stub System.Data.SqlClient.dll (which always throws the platform exception) and platform-specific artifacts in the runtimes directory.

When then running the application using the .NET 6.0.8 runtime, for some reason, the stub System.Data.SqlClient.dll is loaded at execution, whereas using .NET 6.0.0 loads runtimes/unix/lib/netcoreapp2.1/System.Data.SqlClient.dll. It seems the issue is somewhere within the .NET runtime, not within SqlClient itself.

EDIT: This is on Rocky Linux 8, for reference.

alex-jitbit commented 2 years ago

@Wraith2 Like you suggested I tried creating an issue with the nuget team, but they said the problem is with SqlClient, not nuget (see their response in the linked issue)

Again, to recap:

morvoso commented 2 years ago

I'm getting this issue with PopOS 22 ( which is based on ubuntu I believe ). I specify the RID and it still appears. All my other code works fine except for this SqlClient package.

mruf commented 2 years ago

I have the same issue after updating to the latest version of PopOS 22.04:

System.PlatformNotSupportedException: Microsoft.Data.SqlClient is not supported on this platform

Microsoft.Data.SqlClient is the latest version 5.0.0.

Here's my SDK and runtime versions:

6.0.108 [/usr/lib/dotnet/dotnet6-6.0.108/sdk]

Microsoft.AspNetCore.App 6.0.8 [/usr/lib/dotnet/dotnet6-6.0.108/shared/Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.8 [/usr/lib/dotnet/dotnet6-6.0.108/shared/Microsoft.NETCore.App]

mruf commented 2 years ago

I got it working by doing the following (based on steps from here: https://github.com/dotnet/core/issues/7699)

  1. sudo apt remove dotnet*
  2. sudo apt remove aspnetcore*
  3. Create file: sudo touch /etc/apt/preferences
  4. Add the following contents to the file:

Package: * Pin: origin "packages.microsoft.com" Pin-Priority: 1001

  1. sudo apt install dotnet-sdk-6.0

This will install a newer SDK version (6.0.400 [/usr/share/dotnet/sdk]) which apparently solves this problem.

JRahnama commented 2 years ago

@alex-jitbit does the provided solution work for you?

alex-jitbit commented 2 years ago

@JRahnama I will run my tests and get back to you.

MarkpageBxl commented 2 years ago

I believe the issue may be related to missing RIDs, such as for Rocky Linux, in the runtime. I've opened PR dotnet/runtime#74164 for Rocky Linux on the 6.0 servicing line.

Alex-Sob commented 2 years ago

I noticed that if I build .NET 6 project referencing System.Data.SqlClient package on Windows, then System.Data.SqlClient.dll is copied to the bin folder which is a stub assembly where everything throws PlatformNotSupportedException. At runtime the proper assembly is loaded from bin\runtimes subfolder. Is that the expected behavior that bin contains stub assembly after build? Or a bug?

JRahnama commented 2 years ago

@Alex-Sob the part that the assembly is loaded from bin/runtimes is expected.

Alex-Sob commented 2 years ago

@JRahnama Yes, but my question is - does that make sense that after build bin folder contains stub assembly that contains only code throwing PlatformNotSupportedException? Why not copy assembly for the current platform/architecture?

MarkpageBxl commented 2 years ago

@Alex-Sob Because the stub assembly is the fallback in case the .NET runtime's RID inference logic fails, i.e. it doesn't find any specific runtime implementation of the assembly at hand. In the current state of things, there is a gap in .NET 6.0 in the sense that Rocky Linux (and I assume Alma as well) are not supported by the runtime identifier detection logic.

Effectively, depending on the platform, the .NET runtime may not be able to infer the OS to be either win-x64 or linux-x64 (which are the two implementations provided by System.Data.SqlClient IIRC), and thus falls back on the stub implementation, which just throws platform not supported exceptions on every single method.

In other words, the gap is in the .NET runtime RID inference logic, not in SqlClient itself. I suspect other libraries which have the same stub+specific implementation structure will have the same problem.

I've submitted a PR to fill in the gap for Rocky Linux, but it probably needs to be done for other distributions such as Alma as well.

MarkpageBxl commented 2 years ago

P.S. This mechanism is in fact what enables applications to be distributed while targeting several runtime platforms. You can of course override the RID during publishing (e.g. linux-x64), but in that case, the application will only run on that specific platform.

gumbarros commented 2 years ago

Anyone solved this on Pop!_OS 22.04?

EDIT: Solved installing the dotnet SDK manually and setting the path manually on Rider.

image https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-6.0.401-linux-x64-binaries image

jsheely commented 2 years ago

So I've been working on this problem for a little bit and here is what I've encountered

  1. Installing apt install dotnet6 causes the problem
  2. The solution provided by @mruf https://github.com/dotnet/SqlClient/issues/1643#issuecomment-1223716988 did not work for me
  3. **Manually installing the SDK into a folder from the dot.net downloads page and changing my /usr/bin/dotnet symbolic link path to that custom folder did resolve the problem... BUT

Example sudo ln -s /usr/lib/dotnet/custom/dotnet /usr/bin/dotnet

**Step 3 introduced a new bug/problem. I was able to get the application to startup and run but noticed that several of my EF Core queries stopped returning data. Even though the logged query should have returned something.

[EDIT] Upon further inspection my PC is set to EST and the date was suppose to be UTC and it made a conversion which is why the query returned different reuslts. This is likely my bug. Step 3 is the winner**

  1. Running the application using a docker container referencing image mcr.microsoft.com/dotnet/sdk:6.0-jammy does work fine. Which confuses me because I am on the same version of Ubuntu (POP_OS!)
iihmsunn commented 2 years ago

Apparently this problem is affected by the value of RuntimeInformation.RuntimeIdentifier I ran into it by moving from Fedora 36 to Nobara 36 which is just Fedora with some modifications.

I went to /etc/os-release and changed ID from "nobara" to "fedora", which also changed RuntimeInformation.RuntimeIdentifier from "nobara.36-x64" to "fedora.36-x64" and everything worked again, so I guess it may be possible to fiddle with some of the values in this (or similar) file on other systems to make them fit into supported whitelist. I understand this can probably be dangerous and is not something anyone should normally do but maybe this information can be helpful to some people.

I tried looking into possibility of temporarily changing these values just to run dotnet and apparently on systems with lsb_release like Ubuntu it is possible to set path to os info with LSB_ETC_LSB_RELEASE variable but I don't see anything of the sort for Fedora/Red Hat. You can install lsb_release on Fedora but idk if this would change anything.

lcheunglci commented 2 years ago

closing this as it's not an issue with the Microsoft.Data.SqlClient client package.

AraHaan commented 2 years ago

I was able to bypass this issue by putting all of EFCore (and Microsoft.Data.SqlClient) into generic linux-* rids and then manually installing them via extraction from tar.gz files into the $DOTNET_ROOT this resulted in when I tried to run my discord bot in it working on all linux based OS's because I used the generic linux based RIDs for them (and it with r2r).

Also doing such bypass as an experiment also allowed me to be able to roll forward new updates to efcore to the discord bot without needing to rebuild which for me is a bonus because of servicing releases being considered critical for me (also the fact that rebuilding can be a nightmare).

cinmay commented 2 years ago

Anyone solved this on Pop!_OS 22.04?

EDIT: Solved installing the dotnet SDK manually and setting the path manually on Rider.

image https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-6.0.401-linux-x64-binaries image

I managed to get it running using this workaround. Note: Frist I tried using the installer script dotnet-install.sh, but that didn't work. Simply downloading and extracting the binary manually worked fine.

cinmay commented 2 years ago

closing this as it's not an issue with the Microsoft.Data.SqlClient client package.

Does anyone have a link to another bug report? I'm not sure I understand the problem correctly, and I can't find out where to go to follow up on this issue.

GaganKumar98 commented 2 years ago

Have you tried using the latest SDK?

Yes I do But still facing the same Issue