Billionmail/BillionMail · error
environment file not found:
Error message
environment file not found:
What it means
DockerEnv in core/internal/service/public/common.go reads an environment variable from the Docker .env file located at AbsPath(consts.DEFAULT_DOCKER_ENV_FILE). If that file does not exist on disk it returns "environment file not found: <path>". This means the deployment's .env file is missing from the expected location, not that the specific env var is missing.
Source
Thrown at core/internal/service/public/common.go:2407
g.Log().Error(context.Background(), "ReloadFirewall error: ", err, " ", s)
return
}
return
}
// DockerApiFromCtx Get Docker API from context
func DockerApiFromCtx(ctx context.Context) *docker.DockerAPI {
return ctx.Value(consts.DEFAULT_DOCKER_CLIENT_CTX_KEY).(*docker.DockerAPI)
}
// DockerEnv get Docker Environment Configuration
func DockerEnv(envName string) (envVal string, err error) {
// Read environment from ../.env
envFile := AbsPath(consts.DEFAULT_DOCKER_ENV_FILE)
if !FileExists(envFile) {
err = errors.New("environment file not found: " + envFile)
return
}
// Read each lines
err = ReadEach(envFile, func(row string, cnt int) bool {
// Trim whitespace
row = strings.TrimSpace(row)
// Ingore empty line
if row == "" {
return true
}
// Ingore comment line
if strings.HasPrefix(row, "#") {
return true
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Create the .env file at the resolved path (copy .env.example to .env and fill values).
- Verify the working directory: print the path from the error message and check it exists with ls.
- If running outside Docker, mount or symlink the .env file into the expected location.
- Alternatively set the variable in the actual OS environment and adjust code to prefer os.LookupEnv with file fallback.
Example fix
// before
val, err := public.DockerEnv("SMTP_HOST") // environment file not found: /opt/app/.env
// after
cp .env.example /opt/app/.env # then
val, err := public.DockerEnv("SMTP_HOST") Defensive patterns
Strategy: validation
Validate before calling
envFile := public.AbsPath(consts.DEFAULT_DOCKER_ENV_FILE)
if !public.FileExists(envFile) {
return fmt.Errorf(".env missing at %s: copy .env.example first", envFile)
}
val, err := public.DockerEnv("SOME_VAR") Try / catch
val, err := public.DockerEnv(name)
if err != nil {
if strings.HasPrefix(err.Error(), "environment file not found:") {
log.Printf("%v — falling back to OS env", err)
val = os.Getenv(name)
return val, nil
}
return err
} Prevention
- Ship a startup check that verifies .env exists and fails fast with instructions
- Document that the app must run from its deploy directory so AbsPath resolves correctly
- Mount .env into containers explicitly in docker-compose.yml
- Add .env existence to health checks
When it happens
Trigger: Calling DockerEnv("SOME_VAR") when ../.env (relative to the binary, via AbsPath) was never created, was deleted, or the process is running from a different working directory so AbsPath resolves to a wrong/nonexistent path.
Common situations: Running the app outside the standard Docker Compose layout (bare-metal dev run), fresh checkout without copying .env.example to .env, container started without the .env volume mounted, or changed install directory.
Related errors
- failed to update BILLIONMAIL_HOSTNAME in .env file: %v
- Failed to get configuration
- supplier configuration not found
- failed to create Docker client: %v
- failed to update postfix master config: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/083ad47acf61fdb4.
Report an issue: GitHub.