{"record":{"id":"acf578f6d930b812","repo":"ory/kratos","slug":"failed-to-unmarshal-notify-previous-addresses-conf","errorCode":null,"errorMessage":"failed to unmarshal notify_previous_addresses configuration for %s: %w","messagePattern":"failed to unmarshal notify_previous_addresses configuration for (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"driver/registry_default_hooks.go","lineNumber":114,"sourceCode":"\t\t\t}\n\t\tcase hook.KeyVerificationUI:\n\t\t\tif h, ok := any(m.HookShowVerificationUI()).(T); ok {\n\t\t\t\thooks = append(hooks, h)\n\t\t\t}\n\t\tcase hook.KeyVerifier:\n\t\t\tif h, ok := any(m.HookVerifier()).(T); ok {\n\t\t\t\thooks = append(hooks, h)\n\t\t\t}\n\t\tcase hook.KeyVerifyNewAddress:\n\t\t\tif h, ok := any(m.HookVerifyNewAddress()).(T); ok {\n\t\t\t\thooks = append(hooks, h)\n\t\t\t}\n\t\tcase hook.KeyNotifyPreviousAddresses:\n\t\t\tcfg := &hook.NotifyPreviousAddressesConfig{}\n\t\t\tif len(hookConfig.Config) > 0 {\n\t\t\t\tif err := json.Unmarshal(hookConfig.Config, cfg); err != nil {\n\t\t\t\t\tm.l.WithError(err).WithField(\"raw_config\", string(hookConfig.Config)).Error(\"failed to unmarshal hook configuration, ignoring hook\")\n\t\t\t\t\treturn nil, errors.WithStack(fmt.Errorf(\"failed to unmarshal notify_previous_addresses configuration for %s: %w\", credentialsType, err))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif h, ok := any(m.HookNotifyPreviousAddresses(cfg)).(T); ok {\n\t\t\t\thooks = append(hooks, h)\n\t\t\t}\n\t\tdefault:\n\t\t\tfor name, newHook := range m.injectedSelfserviceHooks {\n\t\t\t\tif name == hookConfig.Name {\n\t\t\t\t\tif h, ok := newHook(hookConfig, m).(T); ok {\n\t\t\t\t\t\thooks = append(hooks, h)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue allHooksLoop\n\t\t\t\t}\n\t\t\t}\n\t\t\tm.l.\n\t\t\t\tWithField(\"for\", credentialsType).\n\t\t\t\tWithField(\"hook\", hookConfig.Name).\n\t\t\t\tWarn(\"A configuration for a non-existing hook was found and will be ignored.\")","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/driver/registry_default_hooks.go#L96-L132","documentation":"getHooks decodes a notify_previous_addresses hook's optional JSON config into hook.NotifyPreviousAddressesConfig. If the raw bytes are non-empty but invalid JSON or of the wrong shape, construction of the hook chain is aborted with this wrapped error naming the credentials type. Unlike the web_hook case, an empty config is tolerated.","triggerScenarios":"A hook with key \"notify_previous_addresses\" has a non-empty Config field that fails json.Unmarshal into &hook.NotifyPreviousAddressesConfig{} (malformed JSON or incompatible field types).","commonSituations":"Hand-edited JSON in Kratos config with typos; pasting YAML into the JSON config block; wrapping the config in an extra array; using the wrong casing for config keys after copy-paste between environments.","solutions":["Fix the JSON so it parses and matches hook.NotifyPreviousAddressesConfig field types","Leave the config field empty/null if no options are needed — empty config is allowed","Validate with jq -e against the expected schema before applying config","Inspect raw_config in the error log to identify the exact malformed input"],"exampleFix":"// before\n{\"job\": \"notify_previous_addresses\", \"config\": [\"a\", \"b\"]}\n// after\n{\"job\": \"notify_previous_addresses\", \"config\": {}}","handlingStrategy":"validation","validationCode":"// Go: validate notify_previous_addresses config before use\nfunc validNotifyPrevConfig(raw json.RawMessage) error {\n\tif len(raw) == 0 {\n\t\treturn nil // empty config is allowed\n\t}\n\tvar cfg hook.NotifyPreviousAddressesConfig\n\treturn json.Unmarshal(raw, &cfg)\n}","typeGuard":"func isNotifyPrevConfigOK(raw json.RawMessage) bool {\n\tif len(raw) == 0 {\n\t\treturn true\n\t}\n\tvar cfg hook.NotifyPreviousAddressesConfig\n\treturn json.Unmarshal(raw, &cfg) == nil\n}","tryCatchPattern":"hooks, err := reg.PostRecoveryHooks(ctx, credentialsType)\nif err != nil {\n\tlog.WithError(err).Error(\"check notify_previous_addresses hook config JSON\")\n\treturn err\n}","preventionTips":["Omit the config field entirely when the hook needs no options — empty is valid","Lint YAML→JSON conversion to ensure it produces an object, not an array","Validate config with a schema checker in CI before deploy","Copy hook config only from known-good fixtures"],"tags":["json","configuration","unmarshal"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}