Expected:
nuget push MyLib.nupkg -Source https://nuget.org
WARNING: No API Key was provided and no API Key could be found for 'https://nuget.org'. To save an API Key for a source use the 'setApiKey' command.
Pushing NETStandard.Library.1.6.1.nupkg to 'https://nuget.org'...
PUT https://nuget.org/api/v2/package/
Unauthorized https://nuget.org/api/v2/package/ 1091ms
Please provide credentials for: https://nuget.org
UserName: username
Password: **
PUT https://nuget.org/api/v2/package/
Unauthorized https://nuget.org/api/v2/package/ 740ms
Please provide credentials for: https://nuget.org
UserName: username
Password: *
PUT https://nuget.org/api/v2/package/
Unauthorized https://nuget.org/api/v2/package/ 683ms
Please provide credentials for: https://nuget.org
UserName: username
Password: **
PUT https://nuget.org/api/v2/package/
Unauthorized https://nuget.org/api/v2/package/ 616ms
Response status code does not indicate success: 401 (An API key must be provided in the 'X-NuGet-ApiKey' header to use this service).
You must use an API key to upload a package to NuGet.org with nuget.exe.
Alternatively, you can log into www.nuget.org using your username and password to log in and upload the package through the interactive flow there.
There are some servers according to @zhili1208 that don't need an API key.
And we don't know preemptively whether you would need an ApiKey to give you a different experience. That's why you are prompted for the credentials.
So for a server that only works with API key, what would the flow be? Asking for username/password in those cases will just confuse users. ("I provided correct username/password three times and this did not work!")
This isn't a great experience, today, but we don't have anything built into the protocol allowing a server to say if it requires API key or if it requires some other auth mechanism.
Let's leave this issue open to track this protocol improvement. One idea: use the WWW-Authenticate header and enhance the client to observe this header.
We will need to make this a non-breaking change. Also, I don't think overloading WWW-Authenticate is the right plan. Since the API key goes through X-NuGet-ApiKey rather than Authorization, we're not really in sync with the standard auth spec anyways. Perhaps we could introduce a new header:
X-NuGet-AuthType: APIKEY | BASIC
What if it were part of the index.json?
@maartenba, this would help people pushing to index.json but I think many people still push to the V2 source. In fact our docs even say to push to the V2 endpoint still:

But maybe I am missing your full thought. Could you give me an example of what that would look like and the benefits?
Server side change tracked here: https://github.com/NuGet/NuGetGallery/issues/3585
Yeah V2... Drat :-)
Loooooong ago, when NuGet 1.4 was hip, I did a proposal around this on CodePlex, basically introducing additional headers to specify this type of metadata (e.g. which auth mechanism for which operation, what is the push endpoint, what is the symbols endpoint for this server, is SemVer 2 supported, ... - index.json for V2)
Wonder if it would make sense to have such V2 metadata endpoint for these types of things.
We need to revamp the the various mechanism to push packages. Many good suggestions here. Closing this issue in favor of https://github.com/NuGet/Home/issues/6153 where I am planning to put in a proposal that covers all the related scenarios.
Most helpful comment
This isn't a great experience, today, but we don't have anything built into the protocol allowing a server to say if it requires API key or if it requires some other auth mechanism.
Let's leave this issue open to track this protocol improvement. One idea: use the
WWW-Authenticateheader and enhance the client to observe this header.