{"record":{"id":"bc2b53181c5f940c","repo":"Billionmail/BillionMail","slug":"failed-to-update-billionmail-hostname-in-env-file","errorCode":null,"errorMessage":"failed to update BILLIONMAIL_HOSTNAME in .env file: %v","messagePattern":"failed to update BILLIONMAIL_HOSTNAME in \\.env file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/domains/domains.go","lineNumber":119,"sourceCode":"\t\t\t\tUsername:  mailbox + \"@\" + domain.Domain,\n\t\t\t\tPassword:  grand.S(16),\n\t\t\t\tFullName:  mailbox,\n\t\t\t\tIsAdmin:   0,\n\t\t\t\tQuota:     5242880,\n\t\t\t\tLocalPart: mailbox,\n\t\t\t\tDomain:    domain.Domain,\n\t\t\t\tActive:    1,\n\t\t\t})\n\t\t}\n\n\t\t// attempt update hostname in .env file\n\t\thostname := public.MustGetDockerEnv(\"BILLIONMAIL_HOSTNAME\", \"\")\n\n\t\tif hostname == \"\" || hostname == \"mail.example.com\" {\n\t\t\terr = public.SetDockerEnv(\"BILLIONMAIL_HOSTNAME\", public.FormatMX(domain.Domain))\n\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to update BILLIONMAIL_HOSTNAME in .env file: %v\", err)\n\t\t\t}\n\n\t\t\t// update postfix environment parameter\n\t\t\t_, err = public.DockerApiFromCtx(ctx).ExecCommandByName(ctx, consts.SERVICES.Postfix, []string{\"bash\", \"-c\", fmt.Sprintf(\"sed -i '/^BILLIONMAIL_HOSTNAME=/d' /postfix.sh && sed -i '/^#!\\\\/bin\\\\/bash/a BILLIONMAIL_HOSTNAME=%s' /postfix.sh\", public.FormatMX(domain.Domain))}, \"root\")\n\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to update BILLIONMAIL_HOSTNAME in postfix container: %v\", err)\n\t\t\t}\n\n\t\t\t// restart postfix service\n\t\t\terr = public.DockerApiFromCtx(ctx).RestartContainerByName(ctx, consts.SERVICES.Postfix)\n\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to restart postfix container: %v\", err)\n\t\t\t}\n\t\t}\n\n\t\t// catchall","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/domains/domains.go#L101-L137","documentation":"Add (public) sets BILLIONMAIL_HOSTNAME in the .env file to the MX hostname (via public.FormatMX) when it is empty or still the default mail.example.com. This error wraps a failure of public.SetDockerEnv, which writes the .env file. It means the deployment environment variable could not be persisted.","triggerScenarios":"Calling domains.Add/AddDomain for the first (or default-hostname) domain when SetDockerEnv fails — .env file missing, read-only filesystem, permission denied, or the file is malformed/unparseable.","commonSituations":"Docker Compose .env owned by root while app runs unprivileged; container running with read-only rootfs; .env mounted read-only volume; disk full on host.","solutions":["Check the wrapped error: permission denied vs file-not-found on the .env path","Fix .env file permissions/ownership so the process can write it","Ensure the .env path is on a writable volume and disk has space","Set BILLIONMAIL_HOSTNAME manually in .env and restart the stack if automated writes keep failing"],"exampleFix":"// before\nerr = public.SetDockerEnv(\"BILLIONMAIL_HOSTNAME\", public.FormatMX(domain.Domain))\n// after\nif err := public.SetDockerEnv(\"BILLIONMAIL_HOSTNAME\", public.FormatMX(domain.Domain)); err != nil {\n    logger.Warnf(ctx, \"could not persist BILLIONMAIL_HOSTNAME: %v — set it manually in .env\", err)\n    // decide: abort or continue\n}","handlingStrategy":"validation","validationCode":"envPath := \".env\"\nfi, err := os.Stat(envPath)\nif err != nil || fi.IsDir() { return errors.New(\".env file missing — cannot persist BILLIONMAIL_HOSTNAME\") }\nif unix.Access(envPath, unix.W_OK) != nil { return errors.New(\".env not writable by this process\") }","typeGuard":null,"tryCatchPattern":"if err := public.SetDockerEnv(\"BILLIONMAIL_HOSTNAME\", mx); err != nil {\n    if errors.Is(err, fs.ErrPermission) { return fmt.Errorf(\"fix .env ownership/permissions: %v\", err) }\n    return fmt.Errorf(\"failed to update BILLIONMAIL_HOSTNAME in .env file: %v\", err)\n}","preventionTips":["Ensure the .env volume is writable by the app container user at deploy time","Check disk space in health checks","Keep BILLIONMAIL_HOSTNAME set correctly in .env so the auto-set path is skipped","Mount .env as a regular volume, not read-only"],"tags":["docker","env-file","configuration","filesystem"],"backgroundTag":"env-write-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}