{"record":{"id":"79315b43d9fca188","repo":"phacility/phabricator","slug":"err-no-public-mail","errorCode":"err:no-public-mail","errorMessage":"This mail is addressed to the public email address of an object (\"%s\"), but public replies are not enabled on this server. An administrator may have recently disabled this setting, or you may have replied to an old message. Try replying to a more recent message instead.","messagePattern":"This mail is addressed to the public email address of an object \\(\"(.+?)\"\\), but public replies are not enabled on this server\\. An administrator may have recently disabled this setting, or you may have replied to an old message\\. Try replying to a more recent message instead\\.","errorType":"exception","errorClass":"PhabricatorMetaMTAReceivedMailProcessingException","httpStatus":null,"severity":"warning","filePath":"src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php","lineNumber":71,"sourceCode":"          'This mail is addressed to an object (\"%s\") you do not have '.\n          'permission to see: %s',\n          $pattern,\n          $policy_exception->getMessage()));\n    }\n\n    if (!$object) {\n      throw new PhabricatorMetaMTAReceivedMailProcessingException(\n        MetaMTAReceivedMailStatus::STATUS_NO_SUCH_OBJECT,\n        pht(\n          'This mail is addressed to an object (\"%s\"), but that object '.\n          'does not exist.',\n          $pattern));\n    }\n\n    $sender_identifier = $parts['sender'];\n    if ($sender_identifier === 'public') {\n      if (!PhabricatorEnv::getEnvConfig('metamta.public-replies')) {\n        throw new PhabricatorMetaMTAReceivedMailProcessingException(\n          MetaMTAReceivedMailStatus::STATUS_NO_PUBLIC_MAIL,\n          pht(\n            'This mail is addressed to the public email address of an object '.\n            '(\"%s\"), but public replies are not enabled on this server. An '.\n            'administrator may have recently disabled this setting, or you '.\n            'may have replied to an old message. Try replying to a more '.\n            'recent message instead.',\n            $pattern));\n      }\n      $check_phid = $object->getPHID();\n    } else {\n      if ($sender_identifier != $sender->getID()) {\n        throw new PhabricatorMetaMTAReceivedMailProcessingException(\n          MetaMTAReceivedMailStatus::STATUS_USER_MISMATCH,\n          pht(\n            'This mail is addressed to the private email address of an object '.\n            '(\"%s\"), but you are not the user who is authorized to use the '.\n            'address you sent mail to. Each private address is unique to the '.","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/metamta/receiver/PhabricatorObjectMailReceiver.php#L53-L89","documentation":"Thrown by PhabricatorObjectMailReceiver when an inbound email is addressed to an object's PUBLIC reply address (sender identifier 'public') but the 'metamta.public-replies' configuration setting is disabled on this install. The receiver checks the env config before it will trust a public address, because public addresses are weaker (not bound to one user) and only safe when the administrator opted in. The mail is rejected with STATUS_NO_PUBLIC_MAIL and the sender gets a bounce explaining the cause.","triggerScenarios":"A user replies-all or replies to an old notification whose 'To' address encodes sender 'public' (e.g. public+D123+hash@...) while PhabricatorEnv::getEnvConfig('metamta.public-replies') returns false. Specifically: an administrator ran 'config set metamta.public-replies false' (or never enabled it), and a user then mailed an address generated while it was on, or copied a public address from another install/docs.","commonSituations":"Admin disables public replies after they were enabled (users keep old threads in their mail clients); migrating an install that never set the flag; users forwarding bug-report addresses they found in old emails; copying a public handler address out of documentation into a fresh install where the flag defaults off.","solutions":["Enable the feature: bin/config set metamta.public-replies true --stdin (or edit it in Config > Application Settings > MetaMTA), then have the user reply to a NEWER notification so the address was generated under the current setting.","If public mail must stay off, tell the user to reply to a recent message that carries their own private address instead of the public one.","If you administer the install and want this permanent, communicate the change: old public addresses will keep bouncing with this exact message until users switch threads.","If you are developing a receiver, gate public-address generation on the same config flag so users are never handed addresses that will be rejected later."],"exampleFix":"// before: public replies disabled, old public address bounces\n// bin/config set metamta.public-replies false\n// user replies to: public+D123+abcdef@phabricator.example -> err:no-public-mail\n\n// after: enable public replies, use fresh addresses\n// bin/config set metamta.public-replies true\n// user replies to a notification generated AFTER the change","handlingStrategy":"validation","validationCode":"// Before issuing/writing a public object address, check the same gate the receiver uses:\n$publicOk = PhabricatorEnv::getEnvConfig('metamta.public-replies');\nif (!$publicOk) {\n  // generate per-user private addresses instead of a 'public' sender identifier\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never publish an object's public mail address while metamta.public-replies is off — the address is unusable by construction.","When toggling metamta.public-replies off, announce it: every previously issued public address starts failing with this error.","When writing receivers or address generators, condition public address generation on the live config value, not a cached one."],"tags":["metamta","email","inbound-mail","config","public-replies"],"backgroundTag":"mail-reply-address-rejected","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}