gravitational/teleport · warning
webauthn error code %v
Error message
webauthn error code %v
What it means
This is the bare fallback branch of getErrorNameOrLastErr in Teleport's Windows WebAuthn wrapper. It fires when a native WebAuthn call fails, webAuthNGetErrorName returns 0 (the code is unrecognized), AND the last Win32 syscall error is exactly 0 — meaning Windows set no syscall error, so the wrapper can only report the raw numeric WebAuthn error code with no name and no OS detail. It indicates the operation failed but neither the API's name table nor GetLastError explains why.
Source
Thrown at lib/auth/webauthnwin/webauthn_windows.go:224
},
RawID: credential,
},
AttestationResponse: wantypes.AuthenticatorAttestationResponse{
AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: in.jsonEncodedClientData,
},
AttestationObject: bytesFromCBytes(out.cbAttestationObject, out.pbAttestationObject),
},
}, nil
}
func getErrorNameOrLastErr(in uintptr, lastError error) error {
ret := webAuthNGetErrorName(in)
if ret == 0 {
if lastError != syscall.Errno(0) {
return fmt.Errorf("webauthn error code %v and syscall err: %v", in, lastError)
}
return fmt.Errorf("webauthn error code %v", in)
}
errString := windows.UTF16PtrToString((*uint16)(unsafe.Pointer(ret)))
return fmt.Errorf("webauthn error code %v: %v", in, errString)
}
func isUVPlatformAuthenticatorAvailable() (bool, error) {
var out bool
ret, err := webAuthNIsUserVerifyingPlatformAuthenticatorAvailable(&out)
if err != nil {
return false, getErrorNameOrLastErr(ret, err)
}
return out, nil
}
// bytesFromCBytes gets slice of bytes from C type and copies it to new slice
// so that it won't interfere when main objects is free.
func bytesFromCBytes(size uint32, p *byte) []byte {
if p == nil {View on GitHub (pinned to 1283425b60)
Solutions
- Decode the numeric code in the message against Microsoft's WebAuthn HRESULT list to identify the failure.
- Upgrade Teleport so the error-name table includes the newly mapped code.
- Retry the WebAuthn ceremony once — some codes are transient (user presence timeouts).
- If reproducible, file an issue with the numeric code so the mapping table can be extended.
- Test with a different authenticator (Windows Hello vs USB security key) to isolate the device.
Example fix
// before
err := getErrorNameOrLastErr(code, lastErr) // "webauthn error code 536870943" — no context
// after: give callers a typed, decodable error
if lastError != syscall.Errno(0) {
return fmt.Errorf("webauthn error code %v and syscall err: %v", in, lastError)
}
return fmt.Errorf("webauthn error code %v (0x%08X): unknown WebAuthn status; see Microsoft WebAuthn HRESULT docs", in, uint32(in)) Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: only attempt the ceremony when the platform authenticator answers cleanly
available, err := isUVPlatformAuthenticatorAvailable()
if err != nil {
return trace.Wrap(err)
}
if !available {
return trace.BadParameter("WebAuthn unavailable: connect a security key or enable Windows Hello")
} Type guard
// Detect the bare-code form: contains a code but no syscall errno
func isBareWebauthnCodeErr(err error) bool {
if err == nil {
return false
}
msg := err.Error()
return strings.HasPrefix(msg, "webauthn error code ") && !strings.Contains(msg, "syscall err")
} Try / catch
resp, err := MakeCredential(ctx, req)
if err != nil {
if isBareWebauthnCodeErr(err) {
// unrecognized code with no OS detail — usually transient; retry once
if resp, err = MakeCredential(ctx, req); err != nil {
return trace.Wrap(err, "webauthn failed with unmapped code %v; report this code", err)
}
}
return trace.Wrap(err)
} Prevention
- Retry once on bare unmapped codes before failing — many are transient timeouts
- Keep Teleport current so newly published WebAuthn HRESULTs get name mappings
- Record the numeric code in telemetry to correlate with specific devices/OS builds
- Test ceremonies on both Windows Hello and hardware keys to catch device-specific codes early
When it happens
Trigger: GetAssertion, MakeCredential, or isUVPlatformAuthenticatorAvailable returning an unmapped WebAuthn result code while GetLastError() is ERROR_SUCCESS (0) — e.g. the platform authenticator reports a generic/vendor HRESULT without recording a Win32 error, or a status code (like a retry/time-out code) that the wrapper's name table simply doesn't cover.
Common situations: Newer or older WebAuthn.dll returning codes not present in Teleport's mapping table; vendor security keys returning proprietary status codes; Windows Hello timing out without a Win32 error; CI/VDI environments with virtualized authenticators returning unusual codes.
Related errors
- webauthn error code %v and syscall err: %v
- credential not found
- user has only invalid WebAuthn registrations, consider a use
- unexpected nil response from GetAssertion
- unexpected nil response from MakeCredential
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/fc9e31dfc704d04d.
Report an issue: GitHub.