gravitational/teleport · error
cannot fulfill authenticator attachment %q
Error message
cannot fulfill authenticator attachment %q
What it means
The Touch ID authenticator implementation in Teleport only supports the platform attachment (Touch ID / Secure Enclave). When a WebAuthn credential creation request (PublicKeyCredentialCreationOptions) specifies AuthenticatorAttachment of CrossPlatform (e.g. roaming security keys), it cannot be fulfilled and Register fails with this error. It is an early sanity check before building the platform authenticator request.
Source
Thrown at lib/auth/touchid/api.go:251
if origin == "" {
return nil, trace.BadParameter("origin required")
}
if err := cc.Validate(); err != nil {
return nil, trace.Wrap(err)
}
// Ignored cc fields:
// - Timeout - we don't control touch ID timeouts (also the server is free to
// enforce it)
// - CredentialExcludeList - we always allow re-registering (for various
// reasons).
// - Extensions - none supported
// - Attestation - we always to our best (packed/self-attestation).
// The server is free to ignore/reject.
if cc.Response.AuthenticatorSelection.AuthenticatorAttachment == protocol.CrossPlatform {
return nil, fmt.Errorf("cannot fulfill authenticator attachment %q", cc.Response.AuthenticatorSelection.AuthenticatorAttachment)
}
ok := false
for _, param := range cc.Response.Parameters {
// ES256 is all we can do.
if param.Type == protocol.PublicKeyCredentialType && param.Algorithm == webauthncose.AlgES256 {
ok = true
break
}
}
if !ok {
return nil, errors.New("cannot fulfill credential parameters, only ES256 are supported")
}
rpID := cc.Response.RelyingParty.ID
user := cc.Response.User.Name
userHandle := cc.Response.User.ID
// TODO(codingllama): Handle double registrations and failures after keyView on GitHub (pinned to 1283425b60)
Solutions
- Set AuthenticatorSelection.AuthenticatorAttachment to protocol.Platform (or leave it unset/auto) when the request may be served by Touch ID.
- Configure the Teleport server's WebAuthn settings so attachment is not pinned to cross-platform for macOS clients.
- If cross-platform keys are genuinely required, use a different client path (e.g. webauthncli/FIDO2) instead of the Touch ID API.
- Update tests to use Platform attachment when exercising the Touch ID register flow.
Example fix
// before cc.Response.AuthenticatorSelection.AuthenticatorAttachment = protocol.CrossPlatform cred, err := api.Register(cc) // after cc.Response.AuthenticatorSelection.AuthenticatorAttachment = protocol.Platform cred, err := api.Register(cc)
Defensive patterns
Strategy: validation
Validate before calling
if cc != nil && cc.Response.AuthenticatorSelection.AuthenticatorAttachment == protocol.CrossPlatform {
return errors.New("touchid API cannot serve cross-platform authenticators; use platform attachment")
} Type guard
func touchIDCanFulfill(cc *protocol.CredentialCreation) bool {
return cc == nil || cc.Response.AuthenticatorSelection.AuthenticatorAttachment != protocol.CrossPlatform
} Try / catch
cred, err := api.Register(cc)
if err != nil {
if strings.Contains(err.Error(), "cannot fulfill authenticator attachment") {
// fall back to the FIDO2/roaming-key path
return fallbackFIDO2Register(cc)
}
return trace.Wrap(err)
} Prevention
- Leave AuthenticatorAttachment unset (auto) unless you know which client path will serve the request.
- Gate cross-platform attachment requirements to non-macOS or FIDO2 client paths.
- Add a pre-flight check on the client before invoking the Touch ID register API.
When it happens
Trigger: Calling touchid Register (directly or via promptTouchIDRegisterChallenge) with a creation options object whose AuthenticatorSelection.AuthenticatorAttachment is set to protocol.CrossPlatform.
Common situations: Server-side WebAuthn configuration that requests cross-platform (USB/NFC) authenticators while the client is the macOS Touch ID path; test code (TestRegister_rollback, TestLogin_*) passing crafted options; shared WebAuthn settings not differentiated per platform.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- credential not found
- touch ID not available
- cannot fulfill credential parameters, only ES256 are support
- cred required for %q ceremony
- picker returned invalid credential: %#v
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/f89a9b38befdd05f.
Report an issue: GitHub.