ory/kratos · error · errors.Errorf
key does not exist in cookie: %+v
Error message
key %s does not exist in cookie: %+v
What it means
x.SessionGetString reads a value out of a gorilla/sessions cookie store by session id and key. When the cookie's value map does not contain the requested key, this error is returned. It means the cookie exists and decodes, but the expected field is missing.
Solutions
- Ensure the key is set with the exact same name before reading (check the session.Set/flash call site).
- Handle the error gracefully: treat missing keys as "no value" and redirect to a fresh flow (e.g. re-authentication) instead of failing.
- Have users clear cookies / start a new session if stale cookies from an older schema are involved.
- Log the cookie contents to verify which keys actually exist before reading.
Example fix
// before val, err := x.SessionGetString(r, store, "sid", "userId") // after val, err := x.SessionGetString(r, store, "sid", "identity_id") // key must match the one used at session.Set
Defensive patterns
Strategy: try-catch
Validate before calling
sess, err := store.Get(r, id)
if err == nil {
if _, ok := sess.Values[key]; !ok { /* key absent — handle before calling SessionGetString */ }
} Type guard
func cookieHasKey(sess *sessions.Session, key interface{}) bool {
_, ok := sess.Values[key]
return ok
} Try / catch
val, err := x.SessionGetString(r, store, id, key)
if err != nil {
log.WithError(err).Info("session cookie missing key; starting fresh flow")
http.Redirect(w, r, startFlowURL, http.StatusSeeOther)
return
} Prevention
- Define session keys as shared constants used by both writer and reader.
- Treat missing cookie keys as expected (flash values are consumed once).
- Invalidate stale cookies after schema/key changes (rotate cookie name).
- Log available keys when debugging unexpected misses.
When it happens
Trigger: Calling x.SessionGetString with a key that was never stored (or already expired/evicted) in the session cookie identified by id: check(map) finds v[key] missing.
Common situations: Reading a flash/session value after the flash message was consumed, mismatched session key names between writer and reader (e.g. "user_id" vs "userId"), or an old cookie created before a code change added the key.
Related errors
- value of key is not of type string in cookie
- array must not be empty
- the wildcard '*' is not accepted here
- requested unknown aal
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/fe305a4197d2aea4.
Report an issue: GitHub.
Appendix: source
Thrown at x/cookie.go:31
// SessionPersistValues adds values to the session store and persists the changes.
func SessionPersistValues(w http.ResponseWriter, r *http.Request, s sessions.StoreExact, id string, values map[string]interface{}) error {
// The error does not matter because in the worst case we're re-writing the session cookie.
cookie, _ := s.Get(r, id)
for k, v := range values {
cookie.Values[k] = v
}
return errors.WithStack(cookie.Save(r, w))
}
// SessionGetString returns a string for the given id and key or an error if the session is invalid,
// the key does not exist, or the key value is not a string.
func SessionGetString(r *http.Request, s sessions.StoreExact, id string, key interface{}) (string, error) {
check := func(v map[interface{}]interface{}) (string, error) {
vv, ok := v[key]
if !ok {
return "", errors.Errorf("key %s does not exist in cookie: %+v", key, id)
} else if vvv, ok := vv.(string); !ok {
return "", errors.Errorf("value of key %s is not of type string in cookie", key)
} else {
return vvv, nil
}
}
var exactErr error
cookie, err := s.GetExact(r, id, func(s *sessions.Session) bool {
_, exactErr = check(s.Values)
return exactErr == nil
})
if err != nil {
return "", err
} else if exactErr != nil {
return "", exactErr
}
View on GitHub (pinned to b86338da04)