ory/hydra · critical
global secret is too short
Error message
global secret is too short
What it means
GetGlobalSecret rejects a configured system secret shorter than 16 characters, because short secrets are brute-forceable for the AES-GCM encryption Hydra applies to cookies and stored secrets. The value is then hashed into a byte secret via x.HashStringSecret.
Source
Thrown at driver/config/provider_fosite.go:31
"github.com/ory/hydra/v2/fosite"
"github.com/ory/hydra/v2/fosite/token/jwt"
"github.com/ory/hydra/v2/x"
)
var _ fosite.GlobalSecretProvider = (*DefaultProvider)(nil)
func (p *DefaultProvider) GetGlobalSecret(ctx context.Context) ([]byte, error) {
secrets := p.getProvider(ctx).Strings(KeyGetSystemSecret)
if len(secrets) == 0 {
p.l.Error("The system secret is not configured. Please provide one in the configuration file or environment variables.")
return nil, errors.New("global secret is not configured")
}
secret := secrets[0]
if len(secret) < 16 {
p.l.Errorf("System secret must be undefined or have at least 16 characters but only has %d characters.", len(secret))
return nil, errors.New("global secret is too short")
}
return x.HashStringSecret(secret), nil
}
var _ fosite.RotatedGlobalSecretsProvider = (*DefaultProvider)(nil)
func (p *DefaultProvider) GetRotatedGlobalSecrets(ctx context.Context) ([][]byte, error) {
secrets := p.getProvider(ctx).Strings(KeyGetSystemSecret)
if len(secrets) < 2 {
return nil, nil
}
rotated := make([][]byte, len(secrets)-1)
for i, secret := range secrets[1:] {
rotated[i] = x.HashStringSecret(secret)
}View on GitHub (pinned to 4174065ffb)
Solutions
- Replace the system secret with a value of at least 16 characters, e.g. `openssl rand -base64 32`
- Update ORY_HYDRA_SECRETS_SYSTEM with the longer secret
- Keep old secrets in the list as rotated values if existing encrypted data must remain readable
Example fix
// before
secrets:
system: ["changeme"]
// after
secrets:
system:
- "bG9uZy1yYW5kb20tc2VjcmV0LXZhbHVlIQ==" Defensive patterns
Strategy: validation
Validate before calling
secret := os.Getenv("ORY_HYDRA_SECRETS_SYSTEM")
if len(secret) > 0 && len(secret) < 16 {
return errors.New("system secret must be at least 16 characters")
} Prevention
- Never hand-type secrets; always generate random 32-byte values
- Add a pre-deploy config check enforcing min length
- When rotating, append the new secret and keep the old one until data is re-encrypted
When it happens
Trigger: Calling GetGlobalSecret when secrets.system[0] (first configured value) has fewer than 16 characters, e.g. `secrets.system: ["short"]`.
Common situations: Developer set a memorable short password like `changeme`; a placeholder value left in production config; a trimmed or truncated environment variable.
Related errors
- global secret is not configured
- issuer URL must be set unless development mode is enabled
- unsupported DSN type
- issuer URL scheme must be HTTPS unless development mode is e
- The DSN connection string looks like a SQLite connection, bu
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/82141905e8c4294d.
Report an issue: GitHub.