ory/kratos · error
err
Error message
err
What it means
This is the sentinel error of Ory Kratos' test `Error` hook (selfservice/hook/error.go:45-53). The hook reads its JSON config at the key matching the executed hook method (e.g. "ExecuteSettingsPreHook") via gjson; when the value is the string "err", `err()` deliberately returns `errors.New("err")` so the flow execution fails. It exists purely to simulate hook failures in integration/e2e tests of flow error handling. Error 110 is the message surfaced through all the Execute* hook wrappers that call `err()`.
Solutions
- Remove the `error` (hook.Error) hook from the affected flow in your Kratos config (selfservice.flows.<flow>.before/after.<method>.hooks) — it is a test-only hook.
- If you want the flow to abort with a proper flow error instead, change the config value from "err" to "abort", which returns the flow's ErrHookAbortFlow rather than errors.New("err").
- Remove the offending key/value (e.g. "ExecuteSettingsPreHook":"err") from the hook's JSON config; `err()` then returns nil and the hook becomes a no-op.
Example fix
// before (kratos.yml)
hooks:
- hook: error
config:
ExecuteSettingsPreHook: "err"
// after
hooks:
- hook: require_verified_address # or remove the hook entirely Defensive patterns
Strategy: validation
Validate before calling
// Before enabling the error hook, check what mode each configured key is in.
for key := range hookConfig {
v := gjson.GetBytes(rawCfg, key).String()
if v == "err" {
log.Fatalf("test hook %s configured with \"err\" - remove it from production config", key)
}
} Type guard
func isErrorHookMode(cfg json.RawMessage, hookKey string) bool {
return gjson.GetBytes(cfg, hookKey).String() == "err"
} Try / catch
if err := flow.Execute(r); err != nil {
if err.Error() == "err" {
// deliberate failure injected by the test `error` hook;
// treat as config mistake, not a runtime fault
return fmt.Errorf("test error hook active: %w", err)
}
return err
} Prevention
- Never register the `hook: error` hook outside of test/e2e configuration files.
- Grep kratos.yml / env-rendered config for 'hook: error' before deploying.
- Prefer the "abort" mode (flow-specific ErrHookAbortFlow) over "err" when testing abort behavior, since it produces a meaningful flow error.
When it happens
Trigger: Registering the `error` hook (hook.Error) in a flow's hook list with a JSON config like {"ExecuteSettingsPreHook":"err"} (or any other Execute* key set to "err"), then running that flow (login, registration, settings, recovery, verification) so the executor invokes the corresponding hook.
Common situations: Developers copy-pasting the `error` hook from Kratos test fixtures into real configuration (selfservice.flows.*.after/pre hooks); leftover test-only config promoted to production; contributing to Kratos and running e2e tests that intentionally fail a flow stage.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- expected to get the DSN as an argument, or the…
- required config value "dsn" was not set
- you must provide `secrets.pagination` for FIPS compliance
- you must provide `secrets.cipher` for FIPS compliance
- you must provide `secrets.cookie` for FIPS compliance
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/edfd79f9e8bc68e2.
Report an issue: GitHub.
Appendix: source
Thrown at selfservice/hook/error.go:49
_ login.PreHookExecutor = new(Error)
_ settings.PostHookPostPersistExecutor = new(Error)
_ settings.PostHookPrePersistExecutor = new(Error)
_ settings.PreHookExecutor = new(Error)
_ verification.PreHookExecutor = new(Error)
_ recovery.PreHookExecutor = new(Error)
)
type Error struct {
Config json.RawMessage
}
func (e Error) err(path string, abort error) error {
switch gjson.GetBytes(e.Config, path).String() {
case "err":
return errors.New("err")
case "abort":
return abort
}
return nil
}
func (e Error) ExecuteSettingsPreHook(w http.ResponseWriter, r *http.Request, _ settings.PreHookExecutorParams) error {
return e.err("ExecuteSettingsPreHook", settings.ErrHookAbortFlow)
}
func (e Error) ExecuteSettingsPrePersistHook(w http.ResponseWriter, r *http.Request, _ settings.PostHookPrePersistExecutorParams) error {
return e.err("ExecuteSettingsPrePersistHook", settings.ErrHookAbortFlow)
}
func (e Error) ExecuteSettingsPostPersistHook(w http.ResponseWriter, r *http.Request, _ settings.PostHookPostPersistExecutorParams) error {
return e.err("ExecuteSettingsPostPersistHook", settings.ErrHookAbortFlow)
}
func (e Error) ExecuteLoginPostHook(w http.ResponseWriter, r *http.Request, g node.UiNodeGroup, a *login.Flow, s *session.Session) error {View on GitHub (pinned to b86338da04)