jstedfast/MailKit · error · ArgumentNullException

password

Error message

password

What it means

The NtlmAuthenticateMessage constructor throws ArgumentNullException when password is null. The password is required to derive the NTLM/NTLMv2 hash used to compute the response, so it must be non-null.

Solutions

  1. Pass a non-null password (string.Empty if intentionally blank).
  2. Ensure credentials are fetched/populated before constructing the message.
  3. Null-check the password and surface a clear configuration error to the user instead of the raw ArgumentNullException.

Example fix

// before
var auth = new NtlmAuthenticateMessage(negotiate, challenge, user, null, domain, ws);
// after
if (password == null) throw new InvalidOperationException("NTLM password was not configured.");
var auth = new NtlmAuthenticateMessage(negotiate, challenge, user, password, domain, ws);
Defensive patterns

Strategy: validation

Validate before calling

if (password == null) throw new InvalidOperationException("NTLM password is not configured.");
var auth = new NtlmAuthenticateMessage(negotiate, challenge, userName, password, domain, workstation);

Type guard

static bool HasPassword(string password) => password != null; // empty string is legal

Try / catch

try {
	auth = new NtlmAuthenticateMessage(negotiate, challenge, userName, password, domain, workstation);
} catch (ArgumentNullException ex) when (ex.ParamName == "password") {
	// re-fetch credentials from the secure store before retrying
	password = credentialStore.Get(userName) ?? string.Empty;
}

Prevention

When it happens

Trigger: Calling new NtlmAuthenticateMessage(negotiate, challenge, userName, null, domain, workstation) — typically a missing credential in config, a keychain lookup returning null, or a CredentialCache miss.

Common situations: Password not loaded from configuration/environment; using cached credentials that were never stored; API changes where the password field was renamed.

Related errors


AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15). Data as JSON: /api/errors/f03243ba059382e8. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Security/Ntlm/NtlmAuthenticateMessage.cs:54

		static readonly byte[] Z16 = new byte[16];

		readonly NtlmNegotiateMessage? negotiate;
		readonly NtlmChallengeMessage? challenge;
		byte[] clientChallenge;

		public NtlmAuthenticateMessage (NtlmNegotiateMessage negotiate, NtlmChallengeMessage challenge, string userName, string password, string domain, string workstation) : base (3)
		{
			if (negotiate == null)
				throw new ArgumentNullException (nameof (negotiate));

			if (challenge == null)
				throw new ArgumentNullException (nameof (challenge));

			if (userName == null)
				throw new ArgumentNullException (nameof (userName));

			if (password == null)
				throw new ArgumentNullException (nameof (password));

			clientChallenge = NtlmUtils.NONCE (8);
			this.negotiate = negotiate;
			this.challenge = challenge;

			if (!string.IsNullOrEmpty (domain)) {
				Domain = domain;
			} else if ((challenge.Flags & NtlmFlags.TargetTypeDomain) != 0) {
				// The server is domain-joined, so the TargetName will be the domain.
				Domain = challenge.TargetName ?? string.Empty;
			} else if (challenge.TargetInfo != null) {
				// The server is not domain-joined, so the TargetName will be the machine name of the server.
				Domain = challenge.TargetInfo.DomainName ?? string.Empty;
			} else {
				Domain = string.Empty;
			}

			Workstation = workstation;

View on GitHub (pinned to 9d3859a785)