gravitational/teleport · error

unexpected nil response from MakeCredential

Error message

unexpected nil response from MakeCredential

What it means

MakeCredential calls WebAuthNAuthenticatorMakeCredential in webauthn.dll to register a new credential (Windows Hello or FIDO2 security key). If the API returns success (ret == 0) but the out *webauthnCredentialAttestation pointer is still nil, the wrapper cannot build a CredentialCreationResponse and returns this sentinel error rather than crashing on a nil dereference.

Source

Thrown at lib/auth/webauthnwin/webauthn_windows.go:192

// webauthn.dll and returns CredentialCreationResponse.
// It interacts with both FIDO2 and Windows Hello depending on opts
// (using auto starts with Windows Hello but there is
// option to select other devices).
// Windows Hello keys are always resident.
func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (*wantypes.CredentialCreationResponse, error) {
	hwnd, err := getForegroundWindow()
	if err != nil {
		return nil, trace.Wrap(err)
	}

	var out *webauthnCredentialAttestation
	ret, err := webAuthNAuthenticatorMakeCredential(
		hwnd, in.rp, in.user, in.credParameters, in.clientData, in.opts, &out)
	if ret != 0 {
		return nil, trace.Wrap(getErrorNameOrLastErr(ret, err))
	}
	if out == nil {
		return nil, errors.New("unexpected nil response from MakeCredential")
	}

	// Note that we need to copy bytes out of `out` if we want to free object.
	// That's why bytesFromCBytes is used.
	defer freeCredentialAttestation(out)

	credential := bytesFromCBytes(out.cbCredentialID, out.pbCredentialID)

	return &wantypes.CredentialCreationResponse{
		PublicKeyCredential: wantypes.PublicKeyCredential{
			Credential: wantypes.Credential{
				ID:   base64.RawURLEncoding.EncodeToString(credential),
				Type: string(protocol.PublicKeyCredentialType),
			},
			RawID: credential,
		},
		AttestationResponse: wantypes.AuthenticatorAttestationResponse{
			AuthenticatorResponse: wantypes.AuthenticatorResponse{

View on GitHub (pinned to 1283425b60)

Solutions

  1. Retry the registration; transient Hello/TPM states often succeed on a second attempt.
  2. Install Windows updates to get a fixed webauthn.dll and re-check Windows Hello enrollment in Sign-in options.
  3. Register using a hardware security key (or a different authenticator attachment) instead of Windows Hello.
  4. If reproducible on a supported, updated Windows version, report the bug to Teleport.
Defensive patterns

Strategy: fallback

Validate before calling

// Check native support and platform authenticator availability before registration:
if !native.HasCompileSupport() || !native.IsAvailable() {
    // choose a non-native registration path
}

Type guard

func attestationAvailable(out *webauthnCredentialAttestation) bool { return out != nil }

Try / catch

resp, err := native.MakeCredential(origin, req)
if err != nil {
    if strings.Contains(err.Error(), "unexpected nil response") {
        // retry once, then fall back to security-key registration
    }
    return trace.Wrap(err)
}

Prevention

When it happens

Trigger: Calling nativeImpl.MakeCredential during credential registration (e.g. `tsh mfa add`, device enrollment) when WebAuthNAuthenticatorMakeCredential reports HR_SUCCESS but does not populate the WEBAUTHN_CREDENTIAL_ATTESTATION output.

Common situations: Buggy webauthn.dll on outdated Windows installs; Windows Hello enrollment in a corrupt state during new-credential creation; TPM/attestation failures that the DLL masks as success; virtual machines without a working platform authenticator.

Related errors


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/75e1fc08b158fae4. Report an issue: GitHub.