phalcon/cphalcon · error · Phalcon\Session\Exceptions\SessionAlreadyStarted

The session has already been started. To change the id, use

Error message

The session has already been started. To change the id, use regenerateId()

What it means

Manager::setId() assigns a new session id before the session starts; once a session is active (Manager::exists() true, session_status active) the id is already in use, so Phalcon throws SessionAlreadyStarted and points you to regenerateId().

Source

Thrown at phalcon/Session/Manager.zep:275

     */
    public function setAdapter(<SessionHandlerInterface> adapter) -> <ManagerInterface>
    {
        let this->adapter = adapter;

        return this;
    }

    /**
     * Set session Id
     *
     * @return ManagerInterface
     * @throws InvalidSessionId
     * @throws SessionAlreadyStarted
     */
    public function setId(string sessionId) -> <ManagerInterface>
    {
        if unlikely (true === this->exists()) {
            throw new SessionAlreadyStarted();
        }

        if unlikely !preg_match("/^[a-zA-Z0-9,-]+$/D", sessionId) {
            throw new InvalidSessionId();
        }

        session_id(sessionId);

        return this;
    }

    /**
     * Set the session name. Throw exception if the session has started
     * and do not allow poop names
     *
     * @param string $name
     *
     * @return ManagerInterface

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Call setId() before start(), immediately after creating the Manager and setting the adapter
  2. To rotate the id of a live session (session fixation defense) use $session->regenerateId(true)
  3. Disable session.auto_start so the Manager owns session startup
  4. Guard the call: if (!$session->exists()) { $session->setId($id); }

Example fix

// before
$session->start();
$session->setId($newId); // SessionAlreadyStarted

// after
if (!$session->exists()) {
    $session->setId($newId);
}
$session->start();
// rotating an already-active session id:
$session->regenerateId(true);
Defensive patterns

Strategy: validation

Validate before calling

if (!$session->exists()) {
    $session->setId($newId);
}
// rotating an active session:
if ($session->exists()) {
    $session->regenerateId(true);
}

Prevention

When it happens

Trigger: Calling $session->setId($id) after $session->start(); PHP auto-starting sessions via session.auto_start=1 so any later setId throws; middleware that pins a custom id running after the session middleware already started the session.

Common situations: Enabling session.auto_start in php.ini or the FPM pool; porting plain-PHP code that called session_id() after session_start(); two components (auth listener and bootstrap) both configuring the session, one too late.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/0f0e12522a52c3d1. Report an issue: GitHub.