ory/hydra · critical · ImmutableError
immutable configuration key
Error message
immutable configuration key "%s" was changed from "%v" to "%v"
What it means
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).
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
Example fix
// before # edit config.yaml system_secret in place while server is running // after $ systemctl restart hydra # apply immutable key changes via restart
Defensive patterns
Strategy: type-guard
Validate before calling
func IsImmutableConfigError(err error) bool {
var ie *configx.ImmutableError
return errors.As(err, &ie)
} Type guard
func AsImmutableError(err error) (*configx.ImmutableError, bool) {
var ie *configx.ImmutableError
ok := errors.As(err, &ie)
return ie, ok
} Try / catch
if err := serve(); err != nil {
if ie, ok := AsImmutableError(err); ok {
log.Fatalf("immutable config key %q changed (%v -> %v); restart required", ie.Key, ie.From, ie.To)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- A DSN is required as a positional argument when not passing…
- a key ID must be specified when multiple JWK sets are…
- a secret for signing HMAC-SHA512/256 is expected to be…
- at least one encryption key must be defined but none were
- cookiex: at least one secret is required
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/e8d896fcab3262b8.
Report an issue: GitHub.
Appendix: source
Thrown at oryx/configx/error.go:24
import (
"fmt"
"github.com/pkg/errors"
)
type ImmutableError struct {
From interface{}
To interface{}
Key string
error
}
func NewImmutableError(key string, from, to interface{}) error {
return &ImmutableError{
From: from,
To: to,
Key: key,
error: errors.Errorf("immutable configuration key \"%s\" was changed from \"%v\" to \"%v\"", key, from, to),
}
}
func (e *ImmutableError) Error() string {
return fmt.Sprintf("immutable configuration key \"%s\" was changed from \"%v\" to \"%v\"", e.Key, e.From, e.To)
}
View on GitHub (pinned to 4174065ffb)