oauth2-proxy/oauth2-proxy · critical
could not read cookie secret file
Error message
could not read cookie secret file
What it means
GetSecret in pkg/apis/options/cookie.go returns the OAuth2 proxy cookie secret either from an inline value or by reading the file at SecretFile. When the secret is not set inline and os.ReadFile of SecretFile fails, it logs and returns this error. The cookie secret is required to encrypt/sign session cookies, so startup or session handling fails.
Source
Thrown at pkg/apis/options/cookie.go:79
HTTPOnly: true,
SameSite: "",
CSRFPerRequest: false,
CSRFPerRequestLimit: 0,
CSRFExpire: time.Duration(15) * time.Minute,
CSRFSameSite: "",
}
}
// GetSecret returns the cookie secret, reading from file if SecretFile is set
func (c *Cookie) GetSecret() (secret string, err error) {
if c.Secret != "" || c.SecretFile == "" {
return c.Secret, nil
}
fileSecret, err := os.ReadFile(c.SecretFile)
if err != nil {
logger.Errorf("error reading cookie secret file %s: %s", c.SecretFile, err)
return "", errors.New("could not read cookie secret file")
}
return string(fileSecret), nil
}
View on GitHub (pinned to 33c2eb92de)
Solutions
- Verify the path in --cookie-secret-file / SecretFile exists and is readable by the proxy process user
- Set the secret inline via cookie secret instead of a file, or fix the mount path in your deployment manifest
- Check file permissions (chmod/chown) and that the mounted secret volume is present
- Regenerate the secret file if it was removed, and reconfigure all replicas to use the same secret
Example fix
// before cookie: secretFile: "/etc/secrets/cookie_secret" // after # ensure the file exists and is mounted: # kubectl create secret generic cookie-secret --from-file=cookie_secret=./cookie_secret cookie: secretFile: "/etc/secrets/cookie_secret/cookie_secret"
Defensive patterns
Strategy: validation
Validate before calling
if opts.SecretFile != "" {
if _, err := os.Stat(opts.SecretFile); err != nil {
return fmt.Errorf("cookie secret file %s unavailable: %w", opts.SecretFile, err)
}
} Try / catch
secret, err := opts.GetSecret()
if err != nil {
if err.Error() == "could not read cookie secret file" {
// fall back to a mounted default or fail fast at startup
}
return err
} Prevention
- Probe SecretFile existence/readability at process startup before serving traffic
- Use a mounted Kubernetes secret with a stable mountPath and subPath
- Run the proxy under a user with read access to the secrets directory
- Set the secret inline as a fallback when file-based secrets are optional
When it happens
Trigger: CookieOptions has empty Secret and a non-empty SecretFile that cannot be read: file missing, wrong path, or unreadable permissions, e.g. Load()/makeCipher()/decodeCSRFCookie() calling GetSecret().
Common situations: Kubernetes secret mounted at a different path than configured; file deleted after rotation; running the proxy as a non-root user without read access; typo in --cookie-secret-file flag.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- secret source is invalid: exactly one entry required, specif
- no configuration file provided
- hmacauth: hash algorithm not supported: name
- could not read client secret file
- error initialising cipher: %v
AI-assisted analysis of oauth2-proxy/oauth2-proxy@33c2eb92de (2026-09-06).
Data as JSON: /api/errors/764fa48f23e9876d.
Report an issue: GitHub.