ory/kratos · warning
no identifier found
Error message
no identifier found
What it means
errNoDisplayNameTrait signals that the identity JSON schema does not flag any trait as a passkey display name or WebAuthn identifier and offers no untitled trait to fall back to. PasskeyDisplayNameFromSchema returns it, and the passkey registration strategy uses errors.Is to skip the passkey method gracefully when it is misconfigured. It is a sentinel error, not an end-user message.
Solutions
- Add a title (e.g. 'email' or annotate as WebAuthn identifier) to the trait that should serve as passkey display name in the identity JSON schema
- Use an identity schema with at least one untitled trait the extension can fall back to
- Check skipMethodOnMissingDisplayName behavior: the flow continues with another method, so treat this as a schema misconfiguration warning
Example fix
// before (schema)
{"properties": {"email": {"type": "string", "format": "email"}}}
// after
{"properties": {"email": {"type": "string", "format": "email", "title": "Email", "ory.sh/passkey": {"display_name": true}}}} Defensive patterns
Strategy: fallback
Validate before calling
// pre-check schema: jsonschemax.Paths(...) contains a trait with passkey display-name annotation
Try / catch
if errors.Is(err, errNoDisplayNameTrait) { // fall back to another auth method / log schema misconfiguration
return nil
} Prevention
- Annotate one trait as passkey display name in every identity schema
- Keep trait titles stable when refactoring schemas
- Test registration flows per schema change
When it happens
Trigger: Running passkey registration/ login when the identity schema has no trait annotated as webauthn identifier/display name and no untitled single trait exists.
Common situations: Custom identity schemas that omit passkey-related annotations; renaming traits so the passkey schema extension no longer finds the display name; enabling passkeys with a minimal/default schema lacking the required annotations.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- required credentials not found
- failed to decode PEM block containing private key
- Private key is not ecdsa key
- no oidc provider was set
- the provided number is not a valid phone number
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/d29543d647c7ca69.
Report an issue: GitHub.
Appendix: source
Thrown at selfservice/strategy/passkey/passkey_schema_extension.go:25
"cmp"
"context"
"fmt"
"slices"
"strings"
"sync"
"github.com/pkg/errors"
"github.com/ory/jsonschema/v3"
"github.com/ory/kratos/identity"
"github.com/ory/kratos/schema"
"github.com/ory/x/jsonschemax"
)
// errNoDisplayNameTrait is returned by PasskeyDisplayNameFromSchema when the
// identity schema flags no trait as a passkey display name or WebAuthn
// identifier and has no untitled trait to fall back to.
var errNoDisplayNameTrait = errors.New("no identifier found")
type SchemaExtension struct {
WebauthnIdentifier string
PasskeyDisplayName string
sync.Mutex
}
func (e *SchemaExtension) Run(_ jsonschema.ValidationContext, s schema.ExtensionConfig, value any) error {
e.Lock()
defer e.Unlock()
// When a schema flags multiple traits, the validator visits them in an
// unspecified order. Keep the first non-empty value so an empty flagged
// trait never clobbers a populated one. This mirrors the client, which
// names the passkey after the first non-empty candidate field.
if s.Credentials.WebAuthn.Identifier && e.WebauthnIdentifier == "" {
e.WebauthnIdentifier = strings.ToLower(fmt.Sprintf("%s", value))
}View on GitHub (pinned to b86338da04)