phalcon/cphalcon · error · Phalcon\Container\Exceptions\EnvNotDefined

Environment variable '{varname}' is not defined

Error message

Environment variable '{varname}' is not defined

What it means

Lazy\Env wraps an environment variable and reads it lazily when the service is built. getEnv() merges $_ENV and getenv() and throws EnvNotDefined if the variable appears in neither. Because resolution is deferred, the exception surfaces at container build time — often deep inside service construction — rather than where new Env() was written.

Source

Thrown at phalcon/Container/Resolver/Lazy/Env.zep:98

        }

        return value;
    }

    /**
     * Return the env value
     *
     * @return string
     * @throws EnvNotDefined
     */
    protected function getEnv() -> string
    {
        var envs;

        let envs = array_merge(_ENV, getenv());

        if (!array_key_exists(this->varname, envs)) {
            throw new EnvNotDefined(this->varname);
        }

        return envs[this->varname];
    }
}

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Define the variable in the environment, or load your .env file before the container resolves any service using Env
  2. Guard at boot: if (getenv('DB_HOST') === false && !isset($_ENV['DB_HOST'])) { fail fast with a clear message }
  3. Check exact spelling and case, and export the variable in CLI/cron/unit-test contexts
  4. Assert required variables early in bootstrap so the failure names the missing var, not a stack trace inside a factory

Example fix

// before
$container->set('db', Connection::class)
    ->setConstructorArgs([new Env('DB_HOST')]);
// EnvNotDefined at first get('db') when DB_HOST is unset

// after
// bootstrap.php
$required = ['DB_HOST'];
foreach ($required as $var) {
    if (getenv($var) === false && !isset($_ENV[$var])) {
        throw new RuntimeException('Missing env var: ' . $var);
    }
}
Defensive patterns

Strategy: validation

Validate before calling

function envDefined(string $name): bool
{
    return getenv($name) !== false || isset($_ENV[$name]);
}

// bootstrap assertion, fails fast before any service resolves
foreach (['DB_HOST', 'DB_NAME'] as $var) {
    if (!envDefined($var)) {
        throw new RuntimeException('Missing required environment variable: ' . $var);
    }
}

Try / catch

use Phalcon\Container\Resolver\Lazy\Env;
use Phalcon\Container\Exceptions\EnvNotDefined;

try {
    $value = (new Env('DB_HOST'))->resolve($container);
} catch (EnvNotDefined $e) {
    $value = 'localhost'; // explicit fallback with logging
}

Prevention

When it happens

Trigger: set('db', ...) with a constructor arg of new Env('DB_HOST') while DB_HOST is not defined; the .env loader not run (or run after resolution); variable renamed (DBHOST vs DB_HOST); CLI/cron contexts where the variable was only set for the web SAPI; container secrets not exported in docker/k8s.

Common situations: Deployments where .env loading happens after container build; CI pipelines missing required variables; case mismatches between $_ENV and getenv() sources; local dev works (dotenv loaded) but production fails.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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