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

  1. Ensure the key is set with the exact same name before reading (check the session.Set/flash call site).
  2. Handle the error gracefully: treat missing keys as "no value" and redirect to a fresh flow (e.g. re-authentication) instead of failing.
  3. Have users clear cookies / start a new session if stale cookies from an older schema are involved.
  4. 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

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


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)