{"record":{"id":"3c79c2114d71f1c4","repo":"RocketChat/Rocket.Chat","slug":"warning-push-apn-is-configured-to-production-mode","errorCode":null,"errorMessage":"WARNING: Push APN is configured to production mode - but server is running from localhost","messagePattern":"WARNING: Push APN is configured to production mode - but server is running from localhost","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/meteor/server/lib/notifications/push/apn.ts","lineNumber":136,"sourceCode":"\tlogger.debug('APN configured');\n\n\tif (options.apn.gateway) {\n\t\t// We check the apn gateway i the options, we could risk shipping\n\t\t// server into production while using the production configuration.\n\t\t// On the other hand we could be in development but using the production\n\t\t// configuration. And finally we could have configured an unknown apn\n\t\t// gateway (this could change in the future - but a warning about typos\n\t\t// can save hours of debugging)\n\t\t//\n\t\t// Warn about gateway configurations - it's more a guide\n\n\t\tif (options.apn.gateway === 'gateway.sandbox.push.apple.com') {\n\t\t\t// Using the development sandbox\n\t\t\tlogger.warn('WARNING: Push APN is in development mode');\n\t\t} else if (options.apn.gateway === 'gateway.push.apple.com') {\n\t\t\t// In production - but warn if we are running on localhost\n\t\t\tif (/http:\\/\\/localhost/.test(absoluteUrl)) {\n\t\t\t\tlogger.warn('WARNING: Push APN is configured to production mode - but server is running from localhost');\n\t\t\t}\n\t\t} else {\n\t\t\t// Warn about gateways we dont know about\n\t\t\tlogger.warn({\n\t\t\t\tmsg: 'WARNING: Push APN unknown gateway',\n\t\t\t\tgateway: options.apn.gateway,\n\t\t\t});\n\t\t}\n\t} else if (options.production) {\n\t\tif (/http:\\/\\/localhost/.test(absoluteUrl)) {\n\t\t\tlogger.warn('WARNING: Push APN is configured to production mode - but server is running from localhost');\n\t\t}\n\t} else {\n\t\tlogger.warn('WARNING: Push APN is in development mode');\n\t}\n\n\t// Check certificate data\n\tif (!options.apn.cert?.length) {","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/notifications/push/apn.ts#L118-L154","documentation":"The push APN init detected a contradiction: options.apn.gateway is the production Apple gateway, but the server's absolute URL is http://localhost*, i.e. a local development server sending through production APN. Production pushes require production credentials and a reachable server; this combo usually means leftover production push config on a dev box.","triggerScenarios":"options.apn.gateway === 'gateway.push.apple.com' while ROOT_URL is http://localhost:PORT — e.g. testing push locally with the production push configuration copied from a live server.","commonSituations":"Developers cloning production settings to reproduce a push bug locally; docker-compose dev setups with production env vars; forgetting to switch ROOT_URL/gateway when moving configs between environments.","solutions":["For local testing, switch to sandbox credentials and remove the production gateway","If this server really is production-facing, set ROOT_URL to its public HTTPS URL so the check no longer matches localhost","Keep per-environment config files so dev and prod push settings never mix","Confirm the production push certificate/key are actually installed before relying on production sends"],"exampleFix":"// before\nROOT_URL='http://localhost:3000'\npush: { apn: { gateway: 'gateway.push.apple.com' } }\n\n// after\nROOT_URL='https://chat.example.com'\npush: { apn: { gateway: 'gateway.push.apple.com' } }","handlingStrategy":"validation","validationCode":"const isLocalhostUrl = (url: string): boolean => /http:\\/\\/localhost/.test(url);\n\nif (options.apn.gateway === 'gateway.push.apple.com' && isLocalhostUrl(absoluteUrl)) {\n  throw new Error('Production APN gateway with localhost ROOT_URL — fix ROOT_URL or use sandbox credentials');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set ROOT_URL to the public HTTPS URL on any server using production push config","Never copy production push settings onto a local dev instance","Keep environment-specific config templates to prevent env mixing"],"tags":["push","apn","ios","localhost","configuration"],"backgroundTag":"apn-gateway-misconfiguration","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}