ory/kratos · error
identity schema rejected: invalid regex in pattern
Error message
identity schema rejected: invalid regex in pattern: %w
What it means
preValidateSchema walks an identity schema before handing it to the upstream JSON Schema compiler and pre-compiles every "pattern" value with Go's regexp. If a pattern is not a valid RE2 regular expression, walk returns this wrapped error instead of letting regexp.MustCompile panic deep inside the upstream compile.
Solutions
- Fix the "pattern" value in the identity schema so it compiles as a Go RE2 regular expression (regexp.Compile).
- Remove unsupported constructs: lookaheads/lookbehinds ((?=...), (?!...), (?<=...)) and backreferences are not valid in RE2 — restructure the pattern or validate those parts in application code instead.
- Test the regex locally with a small Go snippet (regexp.Compile) or an RE2-compatible tester before submitting the schema.
- Escape metacharacters that were meant literally (e.g. use \. for a literal dot) to fix 'missing closing )' or 'missing argument to repetition operator' errors.
Example fix
// before "pattern": "^(?=.*[A-Z]).+$" // lookahead, unsupported by RE2 // after "pattern": "^[A-Za-z0-9]*[A-Z][A-Za-z0-9]*$" // RE2-compatible equivalent
Defensive patterns
Strategy: validation
Validate before calling
func validatePattern(p string) error {
if _, err := regexp.Compile(p); err != nil {
return fmt.Errorf("pattern %q invalid: %w", p, err)
}
return nil
} Try / catch
var re *syntax.Error
if errors.As(err, &re) {
log.Printf("fix RE2 regex: %v (code=%v expr=%q)", re, re.Code, re.Expr)
} Prevention
- Test all patterns with Go regexp.Compile before adding them to schemas
- Avoid PCRE-only features (lookarounds, backreferences) — write RE2-compatible patterns
- Escape regex metacharacters when patterns embed literal user text
When it happens
Trigger: An identity schema JSON contains a "pattern" keyword whose string is not a valid Go RE2 regex, e.g. "(?<name>...)" (Go RE2 does not support lookbehind or certain group naming), unbalanced parentheses, or a trailing backslash. Raised during pre-validation of any identity schema submitted for compilation.
Common situations: Patterns copied from JavaScript/PCRE-flavored validators that use lookaheads ((?=...)) or backreferences, which Go's RE2 engine does not support; typos like unclosed character classes; patterns built dynamically from user input that contain regex metacharacters.
Related errors
- identity schema rejected: invalid regex in…
- invalid $ref URL
- identity schema rejected: self-referential $ref cycle
- you must provide `secrets.pagination` for FIPS compliance
- courier: email recipient is not a valid email address
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/a1e9e5fd9332bcc5.
Report an issue: GitHub.
Appendix: source
Thrown at schema/prevalidate.go:87
// Record `$ref` for cycle detection in detectRefCycles. Root
// pointers (`#`, `#/`, empty) map to the empty path. Anything
// without a `#/` prefix is external — out of scope here;
// loadRefURL handles scheme enforcement.
if ref, ok := v["$ref"].(string); ok {
switch {
case ref == "" || ref == "#" || ref == "#/":
p.refs[path] = ""
case strings.HasPrefix(ref, "#/"):
p.refs[path] = strings.TrimPrefix(ref, "#")
}
}
// Pre-compile `pattern` regexes so an invalid one returns a
// kratos-side error instead of panicking deep in
// regexp.MustCompile during the upstream compile.
if pat, ok := v["pattern"].(string); ok {
if _, err := regexp.Compile(pat); err != nil {
return fmt.Errorf("identity schema rejected: invalid regex in pattern: %w", err)
}
}
// patternProperties keys are themselves regexes.
if patternProps, ok := v["patternProperties"].(map[string]any); ok {
for raw := range patternProps {
if _, err := regexp.Compile(raw); err != nil {
return fmt.Errorf("identity schema rejected: invalid regex in patternProperties key %q: %w", raw, err)
}
}
}
for k, sub := range v {
if err := p.walk(sub, path+"/"+escapeJSONPointer(k)); err != nil {
return err
}
}
View on GitHub (pinned to b86338da04)