sdk icon indicating copy to clipboard operation
sdk copied to clipboard

Web Application build error with net6.0 framework, Failed to sign apphost with error code 0

Open techwitz opened this issue 3 years ago • 32 comments

Web Application build error with net6.0 framework.

I am working on MAC and dotnet core 3.1, 5.0 and 6.0 versions are installed on my machine. I not able to build Web Application on my machine due to shared error in this ticket.

I can build web application in target framework net5.0 but not with net6.0 and console, class library projects' build successfully. I tried to build using command line, VS 2022/2019 but no success.

Project file code as below and this is empty Web API project.

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.5" />
  </ItemGroup>

</Project>

To Reproduce

Exceptions (if any)

/usr/local/share/dotnet/sdk/6.0.100-rc.2.21505.57/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(5,5): Error NETSDK1177: Failed to sign apphost with error code 0: /Users/ajandersingh/Projects/WebAppTest/WebAppTest/obj/Debug/net6.0/apphost: is already signed (NETSDK1177) (WebAppTest)

Further technical details

image

  • Include the output of dotnet --info
  • VS 2022 Preview and VS 2019

Please assist to resolve code build error. I apologies if I have posted issue is not relevant to reported category

techwitz avatar Oct 20 '21 09:10 techwitz

@vitek-karas @mateoatr @agocke for triage

dsplaisted avatar Nov 16 '21 21:11 dsplaisted

It looks like up-to-date checking might be confused. If you clear the obj directory and rebuild, does the error still appear?

agocke avatar Nov 16 '21 21:11 agocke

I had a similar issue on a Mac using dotnet 6, which is a console application described in: https://docs.microsoft.com/en-us/learn/modules/work-with-cosmos-db/3-exercise-work-cosmos-db-dotnet

After looking around, the fix for me was to editing the project file and adding:

... true ...

aflores avatar Nov 27 '21 02:11 aflores

I'm having the same issue, without significant changes to our project files. (mac, dotnet6) Removing the obj folder and rebuilding does not solve it. I will report back when I've found a solution.

khellinx avatar Dec 27 '21 13:12 khellinx

Uninstalling the dotnet SDK and reinstalling worked for me. (v6.0.101) To uninstall, I followed the following docs: https://docs.microsoft.com/en-us/dotnet/core/install/remove-runtime-sdk-versions?pivots=os-macos

Don't know what might have caused this to happen but I've tried (a combination of) the following:

  • dotnet clean
  • manually removing obj folders
  • removing all nuget packages
  • remove + reset git dir
  • ... None of which worked until reinstalling the SDK.

This happened after my battery died when multiple asp net apps were running.

khellinx avatar Dec 27 '21 19:12 khellinx

sudo xcode-select -r fixing the issue for me....

shockliang avatar Jan 28 '22 03:01 shockliang

I have tried all these solutions (UseAppHost true, clean all folders, reset xcode-select) to no avail. Anything else I can try here???

joejo-unity avatar Mar 31 '22 18:03 joejo-unity

Here is my recollection of the time line for my experience with this issue. Hope this helps.

Time Line

  1. Before 04/01/22: Experimented with various WebJob telemetry settings
    • ran debug builds in VS Code, command line, everything was fine
  2. 04/01/22: Applied an MacOS update
  3. 04/02/22: Went back to working on the WebJob experiments
    • first build failed with the warning about an existing signature for my WebJob project
  4. Finally found this link .Net 6 AppHost Breaking Changes
  5. Set the UseAppHost to false in the csproj property group
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <UseAppHost>false</UseAppHost>
  </PropertyGroup>
  1. Local builds (VS Code debug and command line) work fine now.

Questions for the MS Folks:

  1. What are the side effects of setting the UseAppHost to false?
  2. Is there a way to address the problem of conflicting app signatures without UseAppHost?

Waste-Treatment avatar Apr 02 '22 17:04 Waste-Treatment

Also... updating Xcode tools after the MacOS update did not help.

Waste-Treatment avatar Apr 02 '22 17:04 Waste-Treatment

I'm on an M1 MacBook Pro, and I too get this issue, but only when using the x64 version of the SDK. The arm64 version works fine. Funny thing is, it worked just fine in both until the last macOS update the other day. Not sure what changed.

In other words, with both the arm64 and x64 versions of the 6.0.201 SDKs installed, the following works fine:

dotnet new console -o TestConsoleApp
cd TestConsoleApp
dotnet build

But then try:

/usr/local/share/dotnet/x64/dotnet build

And I get:

Microsoft (R) Build Engine version 17.1.0+ae57d105c for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  Restored /Users/matt/Code/TestConsoleApp/TestConsoleApp.csproj (in 229 ms).
/usr/local/share/dotnet/x64/sdk/6.0.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(550,5): error NETSDK1177: Failed to sign apphost with error code 0: /Users/matt/Code/TestConsoleApp/obj/Debug/net6.0/apphost: is already signed [/Users/matt/Code/TestConsoleApp/TestConsoleApp.csproj]
/usr/local/share/dotnet/x64/sdk/6.0.201/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(550,5): error NETSDK1177:  [/Users/matt/Code/TestConsoleApp/TestConsoleApp.csproj]

Build FAILED.

Adding <UseAppHost>false</UseAppHost> makes the build pass without error, but then of course there's no app host built.

Aside - Why am I using the x64 SDK at all? Because some of my other projects need to target .NET 5.0 and .NET Core 3.1, and I use JetBrains Rider as my primary IDE. Per their guidance, the x64 toolchain must be used to debug and test properly when multi-targeting.

mattjohnsonpint avatar Apr 05 '22 17:04 mattjohnsonpint

In case it helps, I checked on my mac (under Applications - Utilities - System Information - Software - Installations) and the only updates I see installed in the time period between when it was working and when I started getting the error are "macOS 12.3.1" and "RosettaUpdateAuto" (no version number shown). Both installed 4/1/2022.

Since I'm only seeing it on x64 on an M1, is it possible the issue is related to a change in Rosetta?

mattjohnsonpint avatar Apr 05 '22 17:04 mattjohnsonpint

Looks like a slightly more palatable workaround is to disable code signing of the app host without disabling creation of it. This is controlled by _EnableMacOSCodeSign here: https://github.com/dotnet/sdk/blob/8d1e1e4f39afc2e8338933b9eb014d6a30bc7282/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets#L549-L550

So either of these will turn it off:

  • on the command line

    /usr/local/share/dotnet/x64/dotnet build /p:_EnableMacOSCodeSign=false
    
  • in the csproj

    <PropertyGroup>
       <_EnableMacOSCodeSign>false</_EnableMacOSCodeSign>
    </PropertyGroup>
    

In my case, since I'm only using the x64 toolchain in Rider, I'll do neither of those and just set it in my preferences as a MSBuild global property for now.

image

mattjohnsonpint avatar Apr 05 '22 18:04 mattjohnsonpint

I'm not exactly sure how, but it would appear that even with _EnableMacOSCodeSign disabled, the app host is being signed when build with the x64 SDK. Thus the error message generated by codesign that says that the apphost "is already signed" is correct.

Using the x64 version with signing flag disabled:

/usr/local/share/dotnet/x64/dotnet build --no-incremental /p:_EnableMacOSCodeSign=false
/usr/bin/codesign -dv obj/Debug/net6.0/apphost

Executable=/Users/matt/Code/TestConsoleApp/obj/Debug/net6.0/apphost
Identifier=func-55554944d7d5f799fcc03ab2bf08aa9404d9349c
Format=Mach-O thin (x86_64)
CodeDirectory v=20400 size=1094 flags=0x2(adhoc) hashes=28+2 location=system
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements count=0 size=12

Compare with the arm64 built version with signing enabled:

/usr/local/share/dotnet/dotnet build --no-incremental
/usr/bin/codesign -dv obj/Debug/net6.0/apphost

Executable=/Users/matt/Code/TestConsoleApp/obj/Debug/net6.0/apphost
Identifier=apphost-555549444b3b7104393e3d639bd604424dea5e20
Format=Mach-O thin (arm64)
CodeDirectory v=20400 size=1225 flags=0x2(adhoc) hashes=32+2 location=embedded
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements count=0 size=12

And just for a sanity check, try the arm64 version with signing disabled:

/usr/local/share/dotnet/dotnet build --no-incremental /p:_EnableMacOSCodeSign=false
/usr/bin/codesign -dv obj/Debug/net6.0/apphost                                     

obj/Debug/net6.0/apphost: code object is not signed at all

mattjohnsonpint avatar Apr 05 '22 19:04 mattjohnsonpint

If you can grab an MSBuild binlog, that might tell you more about what's happening -- I agree that signing the apphost should not be happening with _EnableMacOSCodeSign set, and the code doesn't seem to indicate how that would be possible.

There haven't been any recent changes in this area, so it's pretty surprising that this suddenly started failing for you.

agocke avatar Apr 05 '22 19:04 agocke

Captured a binlog, but it doesn't show anything other than CreateAppHost being called, with the code signing flag passed through correctly.

With _EnableMacOSCodeSign set false: image

Without _EnableMacOSCodeSign set false: image

Nothing surprising there.

Digging into the implementation of CreateAppHost, I see it tries to remove the existing signature before sending it on to be signed:

// Remove the signature from MachO hosts.
if (!appHostIsPEImage)
{
    MachOUtils.RemoveSignature(fileStream);
} 

That method returns a boolean success/fail code, but it isn't checked here and I don't see any debug logging. Its implementation is here, and appears to have several places where it could exit early if it didn't detect the type of signature it is expecting. My guess is that something changed with this last macOS 12.3.1 update that makes that code fail on x64-built files (or perhaps just x64-built files when running the code from an arm64 machine under Rosetta?)

Some other clues I just noticed from the signature in my previous post, the Format=Mach-O thin (x86_64) as well as the Identifier starting with func- not apphost-.

mattjohnsonpint avatar Apr 05 '22 20:04 mattjohnsonpint

Good catch -- maybe that's possible. @VSadov could you take a look?

agocke avatar Apr 05 '22 22:04 agocke

I'm baffled about where func- comes from on the identifier. Doing an adhoc code sign with codesign -s - someproject will make the identity start with someproject- so normally it should start with apphost-. Where does func- come from? The only think I can think of called func installed on my machine is the Azure Functions Core Tools, but that shouldn't be involved in this whatsoever. I tried uninstalling that and it still comes out the same way, so 🤷

I also checked the one being passed in as the AppHostSourcePath and it is pre-signed and its identity starts with "apphost-".

mattjohnsonpint avatar Apr 05 '22 23:04 mattjohnsonpint

Hard to see why RemoveSignature would behave differently under Rosetta. It is just parsing/patching of a file. Perhaps the format of signed files has changed when done in x64 emulation.

VSadov avatar Apr 05 '22 23:04 VSadov

I had this problem today, where it failed to sign apphost since it is already signed. It resolved itself and disappeared once I had installed the latest .Net SDK (6.0.202).

I started by trying out the other suggestions, with xcode etc, but this fixed in the end.

iHaveBecomeDeath avatar May 05 '22 11:05 iHaveBecomeDeath

I'm experiencing this on Github Actions OS X runners: https://github.com/imazen/imageflow-dotnet-server/runs/7983577554?check_suite_focus=true#step:11:24 using this workflow: https://github.com/imazen/imageflow-dotnet-server/blob/ca26aa3197887c1520cb32d8ae36647786282f7c/.github/workflows/dotnet-core.yml

MSBuild version 17.3.0+92e077650 for .NET dotnet version 6.0.400 and 3.1.422

lilith avatar Aug 23 '22 21:08 lilith

This pipeline (from the https://github.com/dotnet/iot repository) has an almost 100% repro on this issue now (the MacOS builds are constantly failing). I think this only happens since we use the .NET 7.0 SDK.

pgrawehr avatar Sep 20 '22 18:09 pgrawehr

@elinor-fung could you please take a look at the failing pipelines if there's something we can do to get more information about the failures?

vitek-karas avatar Sep 21 '22 18:09 vitek-karas

I'm baffled about where func- comes from on the identifier.

I also checked the one being passed in as the AppHostSourcePath and it is pre-signed and its identity starts with "apphost-".

Baffling indeed. @mattjohnsonpint would you be able to trace out usage of the apphost file using something like fs_usage (or something else/better - I lack familiarity with macOS tooling).

For the action/pipeline errors from @lilith and @pgrawehr, I suspect the failure is from the IntermediateOutputPath - and therefore AppHostIntermediatePath - being the same for multiple projects. From the binlog of one of the dotnet/iot pipeline failures, Bme280.sample, Bme680.sample, and Bmp280.sample all operate /Users/runner/work/1/s/src/devices/Bmxx80/samples/obj/Debug/net6.0/apphost. The CreateAppHost task for Bme280.sample - which fails with the error saying apphost is already signed - starts while the task for Bme680.sample - which succeeds - is running. The task for Bmp280.sample - which succeeds - starts after the other two have both finished.

I'd think that would be an existing issue (since we started codesign on macOS?) with using the same intermediate path though. @vitek-karas @VSadov do you know if there's a reason we need/want the intermediate file to just be named apphost during signing (or otherwise)? Maybe we should include the assembly name in the intermediate file so that it is something like apphost-$(AssemblyName)?

elinor-fung avatar Sep 22 '22 22:09 elinor-fung

@elinor-fung That indeed makes sense. I created a pull request https://github.com/dotnet/iot/pull/1927 that sets maxCpuCount=1 for the MacOS build and behold, the build succeeded.

pgrawehr avatar Sep 23 '22 05:09 pgrawehr

I agree that there's no reason why the intermediate apphost should be call apphost. Maybe we should rename it to the target name already. So in the above case Bme280.sample or Bme680.sample and so on. In fact I would go one step further and give it an extension which makes it look like non-executable. So something like Bme280.sample.apphost. Especially on Windows this might help with some of the AV problems we've been seeing - and only once the file is done we would copy it to the output path as a real executable.

vitek-karas avatar Sep 23 '22 08:09 vitek-karas

Out of curiosity - do we know why the intermediate path is the same for two projects? I've seen other problems which could be caused by that as well.

vitek-karas avatar Sep 23 '22 08:09 vitek-karas

Out of curiosity - do we know why the intermediate path is the same for two projects? I've seen other problems which could be caused by that as well.

This comes from the current organization of the source. All sample projects for the same device sit in the same directory. In this case, we have src\device\Bmxx80\Bmxx80.csproj which contains the driver modules for three different devices (Bmp280, Bme280 and Bme680). For these three devices, three different samples were added to the same folder. I presume a fix would be to move these projects to their own subfolders. But it does mean that the problem is likely to happen if one has multiple projects in the same directory.

(Side Note: I do try to avoid this, as I have seen weird behavior also on Windows with this. Once I had the problem that the debugger would execute the wrong project when I had two project files in the same directory)

pgrawehr avatar Sep 23 '22 09:09 pgrawehr

Thanks @pgrawehr - I must admit I never thought one would put multiple projects into the same directory... but it does make sense.

vitek-karas avatar Sep 23 '22 09:09 vitek-karas

It's been awhile since I looked into this, but I just tried to reproduce and I can I only do so when setting global.json to target 6.0.201. Targeting 6.0.202 or newer and the issue doesn't appear. (Though I didn't comprehensively test every version of the SDK.)

mattjohnsonpint avatar Sep 23 '22 10:09 mattjohnsonpint

@mattjohnsonpint The project we're talking about above uses the 7.0 preview SDK

pgrawehr avatar Sep 23 '22 11:09 pgrawehr