{"record":{"id":"e8d896fcab3262b8","repo":"ory/hydra","slug":"immutable-configuration-key-s-was-changed-from","errorCode":null,"errorMessage":"immutable configuration key \"%s\" was changed from \"%v\" to \"%v\"","messagePattern":"immutable configuration key \"(.+?)\" was changed from \"(.+?)\" to \"(.+?)\"","errorType":"exception","errorClass":"ImmutableError","httpStatus":null,"severity":"critical","filePath":"oryx/configx/error.go","lineNumber":24,"sourceCode":"import (\n\t\"fmt\"\n\n\t\"github.com/pkg/errors\"\n)\n\ntype ImmutableError struct {\n\tFrom interface{}\n\tTo   interface{}\n\tKey  string\n\terror\n}\n\nfunc NewImmutableError(key string, from, to interface{}) error {\n\treturn &ImmutableError{\n\t\tFrom:  from,\n\t\tTo:    to,\n\t\tKey:   key,\n\t\terror: errors.Errorf(\"immutable configuration key \\\"%s\\\" was changed from \\\"%v\\\" to \\\"%v\\\"\", key, from, to),\n\t}\n}\n\nfunc (e *ImmutableError) Error() string {\n\treturn fmt.Sprintf(\"immutable configuration key \\\"%s\\\" was changed from \\\"%v\\\" to \\\"%v\\\"\", e.Key, e.From, e.To)\n}\n","sourceCodeStart":6,"sourceCodeEnd":31,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/oryx/configx/error.go#L6-L31","documentation":"NewImmutableError builds an ImmutableError raised when a configuration key marked as immutable (must not change at runtime) receives a new value during a live reload. The error captures the key and both the old and new values, and its message states exactly what changed. It typically causes the process to terminate because continuing with a mutated immutable key would be unsafe (e.g. cryptographic secrets).","triggerScenarios":"Changing an immutable config value (commonly secrets like the system secret, cookie keys, or database DSN flagged immutable) while the application is running and a config reload (file watch, env change) picks up the new value — reload() then calls NewImmutableError.","commonSituations":"Rotating secrets via config file edits on a watched file; changing the system secret in Kubernetes Secrets mounted as env/files; editing hydra config in-place instead of restarting the service.","solutions":["Restart the process after changing an immutable key instead of relying on hot reload","Use supported secret rotation mechanisms (e.g. hydra serve with multiple valid system secrets) rather than mutating the immutable key","Update the config in a way that avoids touching immutable keys at runtime; only modify mutable keys live","If it fires at startup unintentionally, check for duplicate config sources (env + file) defining the key with different values"],"exampleFix":"// before\n# edit config.yaml system_secret in place while server is running\n// after\n$ systemctl restart hydra   # apply immutable key changes via restart","handlingStrategy":"type-guard","validationCode":"func IsImmutableConfigError(err error) bool {\n    var ie *configx.ImmutableError\n    return errors.As(err, &ie)\n}","typeGuard":"func AsImmutableError(err error) (*configx.ImmutableError, bool) {\n    var ie *configx.ImmutableError\n    ok := errors.As(err, &ie)\n    return ie, ok\n}","tryCatchPattern":"if err := serve(); err != nil {\n    if ie, ok := AsImmutableError(err); ok {\n        log.Fatalf(\"immutable config key %q changed (%v -> %v); restart required\", ie.Key, ie.From, ie.To)\n    }\n    return err\n}","preventionTips":["Never edit immutable keys (secrets, system secret) in watched config while running — restart instead","Use supported rotation flows (multiple accepted secrets) rather than in-place mutation","Separate mutable and immutable config into different files/sources","Fail fast: treat this error as fatal and alert, since continued runtime with a changed immutable key is unsafe"],"tags":["configuration","hot-reload","immutable","secrets"],"backgroundTag":"immutable-config-changed","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}